# 機能設計書 16-omz changelog

## 概要

本ドキュメントは、Oh My Zshの`omz changelog`コマンドの機能設計について記載する。このコマンドは指定されたバージョンまでの変更履歴（チェンジログ）を表示する機能を提供する。

### 本機能の処理概要

**業務上の目的・背景**：Oh My Zshは頻繁に更新されるプロジェクトであり、ユーザーがアップデート後にどのような変更があったかを確認したいことがある。本機能は、gitのコミット履歴を解析してConventional Commits形式に基づいた構造化されたチェンジログを生成し、ユーザーが変更内容を容易に把握できるようにする。

**機能の利用シーン**：
- Oh My Zshをアップデートした後に変更内容を確認したい場合
- 特定のバージョン間の変更を調べたい場合
- 破壊的変更（BREAKING CHANGES）があったかを確認したい場合
- 新機能やバグ修正の内容を確認したい場合

**主要な処理内容**：
1. 引数で指定されたバージョン（ブランチ、タグ、コミット）を検証する
2. `tools/changelog.sh`スクリプトを呼び出す
3. gitコミット履歴を取得し、Conventional Commits形式で解析する
4. 種別（feat、fix、perf、docs等）ごとに分類して表示する
5. 破壊的変更は特別なセクションで強調表示する

**関連システム・外部連携**：gitリポジトリの履歴を参照する。

**権限による制御**：特になし。gitリポジトリへの読み取り権限があれば実行可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 2 | omz changelog | 主画面 | 指定バージョンまでのチェンジログを表示する処理を実行 |

## 機能種別

データ参照・レポート生成

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| version | 文字列 | No | 表示対象のバージョン（ブランチ/タグ/コミット）。省略時はHEAD | 有効なgit参照かどうか確認 |

### 入力データソース

- Oh My Zshリポジトリのgitコミット履歴
- `oh-my-zsh.lastVersion` git設定（前回バージョン）
- gitタグ情報

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| version | 文字列 | バージョン名（タグ名またはブランチ名） |
| breaking_changes | 配列 | 破壊的変更の一覧 |
| features | 配列 | 新機能の一覧（feat:） |
| fixes | 配列 | バグ修正の一覧（fix:） |
| performance | 配列 | パフォーマンス改善の一覧（perf:） |
| docs | 配列 | ドキュメント変更の一覧（docs:） |
| other_changes | 配列 | その他の変更（refactor:、style:等） |

### 出力先

- 標準出力: フォーマットされたチェンジログ

### 出力形式

3種類の出力形式をサポート：
- `--text`（デフォルト）: ANSIエスケープコードによるカラー表示
- `--raw`: スタイルなしのプレーンテキスト
- `--md`: Markdown形式

**TTY出力例**:
```
master

BREAKING CHANGES

 - abc1234 [plugin] Changed API signature

Features

 - def5678 [git] Added new alias
 - ghi9012 [theme] Support for 256 colors

Bug fixes

 - jkl3456 [docker] Fixed completion error
```

## 処理フロー

### 処理シーケンス

```
1. バージョン引数の検証
   ├─ ブランチとして存在するか確認
   ├─ タグとして存在するか確認
   └─ コミットとして存在するか確認

2. changelog.shスクリプトの呼び出し
   └─ ZSH環境変数を渡して実行

3. コミット履歴の取得
   ├─ 指定バージョンからsinceバージョンまでの範囲を決定
   └─ git logでコミット情報を取得

4. コミットの解析
   ├─ Conventional Commits形式でパース
   ├─ タイプ（feat/fix/docs等）を抽出
   ├─ スコープを抽出
   ├─ サブジェクトを抽出
   └─ 破壊的変更を検出

5. リバートコミットの処理
   └─ リバートされたコミットとリバートコミットを除外

6. 出力フォーマット
   ├─ バージョンヘッダー
   ├─ BREAKING CHANGESセクション
   ├─ 種別ごとのセクション
   └─ その他の変更セクション
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{バージョン引数あり?}
    B -->|No| C[version = HEAD]
    B -->|Yes| D{有効なgit参照?}
    D -->|No| E[使用法を表示して終了]
    D -->|Yes| F[version = $1]
    C --> G[changelog.shを呼び出し]
    F --> G
    G --> H[sinceバージョンを決定]
    H --> I[git logでコミット取得]
    I --> J[各コミットを解析]
    J --> K[タイプ/スコープ/サブジェクト抽出]
    K --> L[破壊的変更を検出]
    L --> M[リバートコミットを除外]
    M --> N[バージョンヘッダー出力]
    N --> O{破壊的変更あり?}
    O -->|Yes| P[BREAKING CHANGESセクション出力]
    O -->|No| Q[種別ごとにセクション出力]
    P --> Q
    Q --> R[その他の変更セクション出力]
    R --> S[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | Conventional Commits解析 | `type[(scope)][!]: subject`形式でコミットを解析 | 常時 |
| BR-02 | 破壊的変更検出 | サブジェクトの`!:`または本文の`BREAKING CHANGE:`で検出 | 常時 |
| BR-03 | リバート除外 | リバートコミットとリバートされたコミットは表示から除外 | 常時 |
| BR-04 | 無視タイプ | `build`、`chore`、`ci`、`test`タイプは表示しない（破壊的変更を含む場合を除く） | 常時 |
| BR-05 | sinceバージョン自動決定 | 指定がない場合、`oh-my-zsh.lastVersion`設定または直前のタグを使用 | since未指定時 |
| BR-06 | コミット数制限 | since未指定時は最大35コミットまで表示 | since未指定時 |

### 計算ロジック

特になし。

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

本機能ではデータベース操作は行わない。gitリポジトリのみを参照する。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 無効なバージョン | 指定されたバージョンが有効なgit参照でない | 使用法を表示して終了（リターンコード1） |
| - | gitリポジトリ外 | $ZSHがgitリポジトリでない | エラーメッセージを出力して終了 |

### リトライ仕様

リトライは行わない。

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

該当なし（読み取り専用操作）。

## パフォーマンス要件

- 通常のコミット数（数百コミット）では数秒以内に処理完了すること
- 大量のコミットがある場合は35コミットで打ち切り

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

- gitリポジトリの読み取り権限のみを使用
- コミット履歴の表示のみで、リポジトリへの書き込みは行わない

## 備考

- ターミナルがハイパーリンクをサポートしている場合、コミットハッシュやイシュー番号がクリック可能なリンクとして表示される
- 出力がパイプされている場合は自動的に`--raw`形式になる

---

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

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

### 推奨読解順序

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

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

**読解のコツ**: この関数はバージョン検証を行い、実際の処理は`tools/changelog.sh`に委譲している。

#### Step 2: changelog.shスクリプトを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | changelog.sh | `tools/changelog.sh` | スクリプト全体の構造（593行）を把握 |

**主要処理フロー**:
1. **1-24行目**: 定数定義（TYPES、MAIN_TYPES、OTHER_TYPES）
2. **43-161行目**: `parse-commit`関数 - コミット解析ロジック
3. **255-481行目**: `display-release`関数 - 出力フォーマット
4. **483-592行目**: `main`関数 - メイン処理

#### Step 3: コミット解析処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | changelog.sh | `tools/changelog.sh` | `parse-commit`関数内のサブ関数群 |

**主要処理フロー**:
- **54-68行目**: `commit:type` - コミットタイプの抽出
- **70-87行目**: `commit:scope` - スコープの抽出
- **89-98行目**: `commit:subject` - サブジェクトの抽出
- **100-119行目**: `commit:is-breaking` - 破壊的変更の検出
- **121-131行目**: `commit:is-revert` - リバートコミットの検出

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

```
omz (lib/cli.zsh 3-21行目)
    │
    └─ _omz::changelog (lib/cli.zsh 185-203行目)
           │
           └─ tools/changelog.sh
                  │
                  ├─ main (483-592行目)
                  │      │
                  │      ├─ git log でコミット取得
                  │      │
                  │      ├─ parse-commit (43-161行目)
                  │      │      ├─ commit:type
                  │      │      ├─ commit:scope
                  │      │      ├─ commit:subject
                  │      │      ├─ commit:is-breaking
                  │      │      └─ commit:is-revert
                  │      │
                  │      └─ display-release (255-481行目)
                  │             ├─ display:version
                  │             ├─ display:breaking
                  │             ├─ display:type (各タイプ)
                  │             └─ display:others
                  │
                  └─ フォーマット関数群
                         ├─ fmt:hash
                         ├─ fmt:header
                         ├─ fmt:scope
                         ├─ fmt:subject
                         └─ fmt:type
```

### データフロー図

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

バージョン引数      ───▶ バージョン検証
                          │
git log             ───▶ コミット取得
                          │
                          ▼
                     parse-commit
                          │
                          ├─ types配列
                          ├─ subjects配列
                          ├─ scopes配列
                          ├─ breaking配列
                          └─ reverts配列
                               │
                               ▼
                     display-release          ───▶ フォーマット済み
                          │                        チェンジログ
                          ├─ BREAKING CHANGES
                          ├─ Features
                          ├─ Bug fixes
                          └─ Other changes
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| cli.zsh | `lib/cli.zsh` | ソース | omzコマンドのCLI実装。_omz::changelog関数を含む |
| changelog.sh | `tools/changelog.sh` | ソース | チェンジログ生成のメインスクリプト |
