# 機能設計書 19-omz pr test

## 概要

本ドキュメントは、Oh My Zshの`omz pr test`コマンドの機能設計について記載する。このコマンドはGitHub Pull Requestをfetchしてmasterにrebaseし、テスト用に新しいzshを起動する機能を提供する。

### 本機能の処理概要

**業務上の目的・背景**：Oh My Zshプロジェクトでは、コントリビューターからのPull Requestをテストする必要がある。本機能は、PRの変更を安全にテストするための仕組みを提供する。特に、未レビューのPRには悪意のあるコードが含まれる可能性があるため、セキュリティチェック機能を備えている。

**機能の利用シーン**：
- コントリビューターが提出したPRをローカルでテストしたい場合
- PRのレビュー前に動作確認を行いたい場合
- PRの変更が既存の設定と互換性があるか確認したい場合
- メンテナーがPRをマージする前に最終確認を行いたい場合

**主要な処理内容**：
1. PR番号またはURLから番号を抽出
2. GitHub APIでPRに「testers needed」ラベルがあるか確認
3. ラベルがない場合はセキュリティ警告を表示し、明示的な確認を求める
4. PRのheadをfetchして`ohmyzsh/pull-<番号>`ブランチを作成
5. masterブランチに対してrebaseを実行
6. 新しいzshセッションを起動してテスト
7. テスト後、元のブランチに戻るか確認

**関連システム・外部連携**：
- GitHub API: PRのラベル情報を取得
- gitリポジトリ: fetch、rebase、checkout操作

**権限による制御**：特になし。ただし、「testers needed」ラベルのないPRは警告が表示される。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 11 | omz pr test | 主画面 | GitHub PRをfetchしてmasterにrebaseし、テスト用に新しいzshを起動 |

## 機能種別

バージョン管理・テスト支援

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| PR_number_or_URL | 文字列 | Yes | PR番号またはPRのURL | 数値のみであること |

### 入力データソース

- GitHub API (`https://api.github.com/repos/ohmyzsh/ohmyzsh/pulls/<番号>`)
- Oh My Zshリポジトリのgitリモート

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| - | - | ログメッセージを標準エラー出力に出力 |

### 出力先

- 標準エラー出力: 処理ステータスのログメッセージ
- ファイルシステム: `ohmyzsh/pull-<番号>`ブランチの作成

### 副作用

- `ohmyzsh/pull-<番号>`ブランチが作成される
- 一時的に`commit.gpgsign`設定が変更される（rebase時）
- 新しいzshセッションが起動される

## 処理フロー

### 処理シーケンス

```
1. 入力の検証
   ├─ URLの場合は末尾の番号を抽出
   └─ 数値のみであることを確認

2. 現在のブランチを保存
   └─ git symbolic-ref --short HEAD

3. ohmyzshリモートの検索
   └─ git remote -v で ohmyzsh/ohmyzsh を検索

4. セキュリティチェック
   ├─ GitHub APIでPR情報を取得
   ├─ "testers needed"ラベルの存在確認
   └─ ラベルがない場合は明示的確認を要求

5. PRのfetch
   └─ git fetch -f $remote refs/pull/$1/head:ohmyzsh/pull-$1

6. masterへのrebase
   ├─ commit.gpgsignを一時的に無効化
   ├─ git rebase master ohmyzsh/pull-$1
   └─ commit.gpgsignを復元

7. テスト用zshの起動
   └─ command zsh -l

8. 元のブランチへの復帰
   ├─ 確認プロンプト表示
   └─ git checkout "$branch"
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{入力がURL?}
    B -->|Yes| C[末尾の番号を抽出]
    B -->|No| D{数値のみ?}
    C --> D
    D -->|No| E[使用法を表示して終了]
    D -->|Yes| F[現在のブランチを保存]
    F --> G[ohmyzshリモートを検索]
    G --> H{リモートが見つかった?}
    H -->|No| I[エラー終了]
    H -->|Yes| J[GitHub APIでPR情報取得]
    J --> K{"testers needed"ラベルあり?}
    K -->|Yes| L[PRをfetch]
    K -->|No| M[セキュリティ警告表示]
    M --> N{"yes"と入力?}
    N -->|No| O[キャンセル終了]
    N -->|Yes| L
    L --> P[masterにrebase]
    P --> Q{rebase成功?}
    Q -->|No| R[警告表示して続行]
    Q -->|Yes| S[成功メッセージ]
    R --> T[新しいzsh起動]
    S --> T
    T --> U[テスト終了後]
    U --> V{元のブランチに戻る?}
    V -->|Yes| W[git checkout $branch]
    V -->|No| X[終了]
    W --> X
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | URL対応 | `https://github.com/ohmyzsh/ohmyzsh/pull/123`形式のURLからも番号を抽出可能 | URL入力時 |
| BR-02 | セキュリティチェック | 「testers needed」ラベルがないPRは警告を表示し、明示的な「yes」入力を要求 | 常時 |
| BR-03 | ブランチ命名規則 | PRブランチは`ohmyzsh/pull-<番号>`の形式で作成 | 常時 |
| BR-04 | GPG署名一時無効化 | rebase中は`commit.gpgsign`を一時的に無効化し、完了後に復元 | rebase時 |
| BR-05 | rebase失敗時の警告 | rebaseが失敗しても警告を表示してテストは継続可能 | rebase失敗時 |

### 計算ロジック

特になし。

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

本機能ではデータベース操作は行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 引数不正 | PR番号が数値でない | 使用法を表示して終了 |
| - | ブランチ取得失敗 | 現在のブランチを取得できない | エラーメッセージを出力して終了 |
| - | リモート未検出 | ohmyzsh/ohmyzshリモートが見つからない | エラーメッセージを出力して終了 |
| - | API取得失敗 | GitHub APIへのリクエストが失敗 | エラーメッセージを出力して終了 |
| - | fetch失敗 | PRのfetchに失敗 | エラーメッセージを出力して終了 |
| - | rebase失敗 | rebaseがコンフリクト等で失敗 | 警告を表示してテストは継続 |

### リトライ仕様

リトライは行わない。

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

擬似的なトランザクション処理を実装：
- rebase失敗時は`git rebase --abort`を実行
- `commit.gpgsign`設定は`always`ブロックで必ず復元

## パフォーマンス要件

- GitHub API呼び出しはネットワーク速度に依存
- PRのfetchとrebaseはPRのサイズに依存

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

- **重要**: 「testers needed」ラベルのないPRは、メンテナーによるレビューが完了していないため、悪意のあるコードが含まれる可能性がある
- ラベルがない場合は明確な警告を表示し、ユーザーに「yes」と入力させることで明示的な同意を求める
- PRのコードはユーザーのシェル環境で実行されるため、信頼できないPRは慎重に扱う必要がある

## 備考

- `jq`コマンドがある場合はそれを使用してJSONを解析、ない場合は`grep`でフォールバック
- テスト用zshは`-l`オプション付きでログインシェルとして起動される
- テスト終了後、元のブランチに戻るか確認される

---

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

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

### 推奨読解順序

#### Step 1: 関数の全体構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | cli.zsh | `lib/cli.zsh` | `_omz::pr::test`関数の定義位置（591-724行目）を確認 |

**読解のコツ**: この関数は複数のサブシェルを使用しており、エラー処理が細かく行われている。`set -e`によりエラー時に即座に終了する。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | cli.zsh | `lib/cli.zsh` | omz関数（3-21行目）からのコマンドディスパッチを確認 |
| 2-2 | cli.zsh | `lib/cli.zsh` | _omz::pr関数（541-559行目）からのサブコマンドディスパッチを確認 |

**主要処理フロー**:
1. **3-21行目**: `omz`関数がコマンドライン引数を解析し、`_omz::$command`を呼び出す
2. **541-559行目**: `_omz::pr`関数が`test`サブコマンドを受け取り、`_omz::pr::test`を呼び出す

#### Step 3: PRテスト処理の詳細を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | cli.zsh | `lib/cli.zsh` | `_omz::pr::test`関数（591-724行目）の実装詳細 |

**主要処理フロー**:
- **592-595行目**: URL形式のPR参照からの番号抽出
- **597-601行目**: 入力の検証
- **603-608行目**: 現在のブランチの保存
- **613-628行目**: ohmyzshリモートの検索
- **630-666行目**: セキュリティチェック（「testers needed」ラベル確認）
- **668-673行目**: PRのfetch
- **675-698行目**: masterへのrebase（GPG署名一時無効化）
- **700-701行目**: 成功メッセージ
- **707-708行目**: テスト用zshの起動
- **710-723行目**: 元のブランチへの復帰

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

```
omz (3-21行目)
    │
    └─ _omz::pr (541-559行目)
           │
           └─ _omz::pr::test (591-724行目)
                  │
                  ├─ 入力検証・ブランチ保存
                  │
                  ├─ (サブシェル1)
                  │      │
                  │      ├─ git remote -v → リモート検索
                  │      │
                  │      ├─ curl → GitHub API
                  │      │
                  │      ├─ jq/grep → ラベル確認
                  │      │
                  │      ├─ git fetch → PR取得
                  │      │
                  │      └─ git rebase → masterにrebase
                  │
                  ├─ command zsh -l → テスト用シェル
                  │
                  └─ (サブシェル2)
                         │
                         └─ git checkout → 元のブランチに復帰
```

### データフロー図

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

PR番号/URL         ───▶ 番号抽出
                          │
                          ▼
GitHub API         ───▶ PR情報取得
                          │
                          ├─ ラベルチェック
                          │      │
                          │      └─ (警告/確認)
                          │
                          ▼
git remote         ───▶ ohmyzshリモート検索
                          │
                          ▼
git fetch          ───▶ PRをfetch            ───▶ ohmyzsh/pull-N ブランチ
                          │
                          ▼
git rebase         ───▶ masterにrebase
                          │
                          ▼
zsh -l             ───▶ テスト用シェル起動    ───▶ 新しいzshセッション
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| cli.zsh | `lib/cli.zsh` | ソース | omzコマンドのCLI実装。_omz::pr::test関数を含む |
