# 機能設計書 10-next upgrade

## 概要

本ドキュメントは、Next.jsバージョンアップグレードコマンド `next upgrade` の機能設計を記述する。@next/codemodパッケージを利用して、Next.jsのバージョンアップグレードとコード自動変換を一括で実行するCLIコマンドである。

### 本機能の処理概要

`next upgrade` コマンドは、Next.jsプロジェクトのバージョンアップグレードを支援するCLIコマンドである。内部的に`@next/codemod`パッケージのupgradeコマンドをnpx経由で実行する。

**業務上の目的・背景**：Next.jsのメジャーバージョンアップグレードには、APIの変更やベストプラクティスの更新が伴うことが多い。手動でのコード修正は工数がかかりミスも発生しやすい。`next upgrade` はバージョン更新とコード自動変換（codemod）を一つのコマンドで実行することで、アップグレード作業を効率化・標準化する。

**機能の利用シーン**：Next.jsの新バージョンへのアップグレード時に使用する。`--revision`オプションでターゲットバージョンを指定でき、latest（安定版）・canary（最新開発版）・rc（リリース候補）・beta・特定のバージョン番号を指定可能。

**主要な処理内容**：
1. プロジェクトディレクトリの解決
2. npxコマンドの取得（パッケージマネージャーに応じた適切なコマンド）
3. `@next/codemod@canary upgrade` の子プロセスとしての実行
4. 指定リビジョンへのアップグレードとコード変換の実行

**関連システム・外部連携**：@next/codemod（コード変換ツール）、npmレジストリ（パッケージ取得）

**権限による制御**：特段の権限制御はない。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 関連画面なし（CLIコンソール出力のみ） |

## 機能種別

CLIコマンド / アップグレード / コード変換

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| directory | string | No | プロジェクトディレクトリ。未指定時はカレントディレクトリ | なし |
| --revision | string | No | ターゲットバージョン（dist-tagまたはバージョン番号） | デフォルト: 現在のインストールチャネルに基づく |
| --verbose | boolean | No | 詳細出力を有効化 | なし |

### 入力データソース

- CLI引数（Commander.jsで解析）
- 現在インストールされているNext.jsのバージョン（デフォルトrevision決定用）
- パッケージマネージャー情報（npxコマンド決定用）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| アップグレード結果 | text | @next/codemodの実行結果（stdout/stderr） |
| 終了コード | number | @next/codemodプロセスの終了コード |

### 出力先

- 標準出力/標準エラー出力（@next/codemodの出力を継承）
- プロジェクトファイル（コード変換の結果としてソースコードが変更される）
- package.json（依存パッケージのバージョン更新）

## 処理フロー

### 処理シーケンス

```
1. プロジェクトディレクトリの解決
   └─ getProjectDir(directory)
2. npxコマンドの取得
   └─ getNpxCommand(baseDir)でパッケージマネージャーに応じたコマンドを取得
   └─ スペースで分割してコマンドと引数を分離
3. 子プロセスコマンドの構築
   └─ [@next/codemod@canary, upgrade, revision]
   └─ --verbose指定時は--verboseフラグを追加
4. 子プロセスの起動（spawn）
   └─ stdio: 'inherit'で親プロセスのI/Oを継承
   └─ cwd: baseDirを作業ディレクトリに設定
5. 終了コードの転送
   └─ 子プロセスのcloseイベントで親プロセスのexitCodeを設定
```

### フローチャート

```mermaid
flowchart TD
    A[next upgrade 実行] --> B[プロジェクトディレクトリ解決]
    B --> C[npxコマンド取得]
    C --> D[コマンド引数構築]
    D --> E{--verbose?}
    E -->|Yes| F[--verboseフラグ追加]
    E -->|No| G[spawn実行]
    F --> G
    G --> H[@next/codemod upgrade 実行]
    H --> I[終了コード転送]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | デフォルトrevisionの決定 | 現在のNext.jsバージョンに基づき適切なチャネルを選択 | --revision未指定時 |
| BR-02 | canaryインストール時 | バージョンに'-canary.'が含まれる場合はデフォルトrevision='canary' | 現在のバージョンがcanaryの場合 |
| BR-03 | rcインストール時 | バージョンに'-rc.'が含まれる場合はデフォルトrevision='rc' | 現在のバージョンがrcの場合 |
| BR-04 | betaインストール時 | バージョンに'-beta.'が含まれる場合はデフォルトrevision='beta' | 現在のバージョンがbetaの場合 |
| BR-05 | 安定版インストール時 | 上記に該当しない場合はデフォルトrevision='latest' | 安定版の場合 |
| BR-06 | @next/codemod@canary使用 | 最新のコード変換を取得するため、常にcanaryバージョンの@next/codemodを使用 | 常時 |
| BR-07 | I/O継承 | 子プロセスのstdio: 'inherit'により、対話的な操作も可能 | 常時 |

### 計算ロジック

デフォルトrevisionの決定ロジック:
```
if (version.includes('-canary.')) -> 'canary'
else if (version.includes('-rc.')) -> 'rc'
else if (version.includes('-beta.')) -> 'beta'
else -> 'latest'
```

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

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

本機能はデータベースを操作しない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | npx実行失敗 | npxコマンドが見つからない | Node.jsとnpmを正しくインストール |
| - | @next/codemod取得失敗 | npmレジストリに接続できない | ネットワーク接続を確認 |
| - | codemod実行エラー | コード変換中のエラー | エラーメッセージに従い手動で対応 |

### リトライ仕様

なし。

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

なし。コード変換はファイルシステムに直接書き込まれる。変換前のコードはGit等のバージョン管理で復元可能。

## パフォーマンス要件

- @next/codemodパッケージのダウンロードにネットワーク時間を要する
- コード変換の実行時間はプロジェクトの規模に依存

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

- @next/codemod@canaryは常にnpmレジストリから最新版を取得するため、サプライチェーン攻撃のリスクに注意
- ソースコードの自動変換が行われるため、変換結果のレビューを推奨

## 備考

- `next upgrade` は内部的に@next/codemodのupgradeコマンドを実行するラッパーである
- @next/codemodは最新のcodemods（コード変換ルール）を取得するためcanaryバージョンを使用する
- spawnで子プロセスを起動し、stdio: 'inherit'で親プロセスのI/Oを継承するため、対話的な操作（確認プロンプト等）もパススルーされる
- process.exitCodeで終了コードを設定（process.exit()ではない）ため、Node.jsのイベントループが適切にクリーンアップされる

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | next-upgrade.ts | `packages/next/src/cli/next-upgrade.ts` | NextUpgradeOptions型定義（5-8行目）。revision（ターゲットバージョン文字列）とverbose（詳細出力フラグ）の2プロパティ |

**読解のコツ**: next-upgrade.tsは41行と非常にコンパクト。spawnNextUpgradeという名前の通り、実際のアップグレードロジックは@next/codemodに完全に委譲されている。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | next.ts | `packages/next/src/bin/next.ts` | upgradeコマンドの定義（466-493行目）。デフォルトrevisionの決定ロジック |
| 2-2 | next-upgrade.ts | `packages/next/src/cli/next-upgrade.ts` | spawnNextUpgrade関数（10-41行目） |

**主要処理フロー**:
1. **465行目（next.ts）**: nextVersionの取得（process.env.__NEXT_VERSION）
2. **478-487行目（next.ts）**: デフォルトrevisionの三項演算子チェーン（canary > rc > beta > latest）
3. **14行目**: getProjectDir(directory)でプロジェクトディレクトリ解決
4. **15-16行目**: getNpxCommand(baseDir)でnpxコマンド取得、split(' ')で分割
5. **18-24行目**: upgradeProcessCommandArgsの構築（@next/codemod@canary, upgrade, revision）
6. **25-27行目**: --verbose指定時にフラグ追加
7. **29-36行目**: spawn実行（stdio: 'inherit', cwd: baseDir）
8. **38-40行目**: closeイベントでexitCodeを設定

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

```
bin/next.ts (CLIエントリーポイント)
    │
    └─ cli/next-upgrade.ts::spawnNextUpgrade()
           ├─ lib/get-project-dir.ts::getProjectDir()
           ├─ lib/helpers/get-npx-command.ts::getNpxCommand()
           └─ child_process.spawn()
                  └─ npx @next/codemod@canary upgrade [revision]
                         └─ @next/codemod (外部パッケージ)
                                ├─ バージョン更新
                                └─ コード変換 (codemods)
```

### データフロー図

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

CLI引数 ─────────────▶ next.ts (Commander解析) ──────▶ revision, verbose
                              │
currentVersion ──────▶ デフォルトrevision決定 ────────▶ 'latest'|'canary'|'rc'|'beta'
                              │
パッケージマネージャー ▶ getNpxCommand() ─────────────▶ npxコマンド文字列
                              │
                       spawn(@next/codemod upgrade) ─▶ ソースコード変更
                                                      ▶ package.json更新
                                                      ▶ 終了コード
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| next.ts | `packages/next/src/bin/next.ts` | ソース | CLIメインエントリーポイント |
| next-upgrade.ts | `packages/next/src/cli/next-upgrade.ts` | ソース | next upgradeコマンドのメイン処理 |
| get-project-dir.ts | `packages/next/src/lib/get-project-dir.ts` | ソース | プロジェクトディレクトリ解決 |
| get-npx-command.ts | `packages/next/src/lib/helpers/get-npx-command.ts` | ソース | パッケージマネージャー対応のnpxコマンド取得 |
