# 機能設計書 12-doom doctor

## 概要

本ドキュメントは、Doom Emacsの診断コマンド「doom doctor」の機能設計を定義する。このコマンドは、システム環境とDoom設定の問題を自動検出し、ユーザーに修正のためのアドバイスを提供する診断ツールである。

### 本機能の処理概要

doom doctorは、Doom Emacsが正常に動作するために必要な前提条件を包括的にチェックし、潜在的な問題を検出する診断コマンドである。

**業務上の目的・背景**：Doom Emacsは多くの外部依存（git, rg, フォント等）を持ち、また複雑なモジュールシステムを採用している。ユーザーがインストール時や運用中に問題に遭遇した場合、その原因を特定するのは困難である。doom doctorは、これらの問題を自動的に検出し、具体的な解決策を提示することで、ユーザーの問題解決を支援する。特に、Doomのissue trackerに報告する前に、ユーザー側で解決可能な問題を洗い出すことで、サポート効率も向上させる。

**機能の利用シーン**：
- Doom Emacsの初回インストール後の環境確認
- Emacsが正常に起動しない場合のトラブルシューティング
- Emacsの動作が不安定な場合の問題診断
- Doomをアップデートした後の環境チェック
- issueを報告する前の事前確認

**主要な処理内容**：
1. Emacsバージョンの確認（開発版、サポート終了版の検出）
2. 必須依存関係のチェック（git, rg）
3. Emacs設定ファイルの競合チェック（.emacs, .emacs.d等）
4. Emacsの機能確認（JSON、ネイティブコンパイル）
5. フォント環境のチェック（Symbola, nerd-icons）
6. プライベート設定の競合チェック
7. 環境変数と一時ファイルディレクトリのチェック
8. 古いelcファイルの検出
9. Git設定の確認
10. 各モジュールのdoctor.elによる個別診断

**関連システム・外部連携**：
- git: バージョン確認、設定確認
- fc-list: フォント検出（fontconfig）
- システムシェル: 環境変数確認

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

## 関連画面

本機能はCLIコマンドであり、GUIの画面は持たない。

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | ターミナル | 主画面 | コマンドライン実行、診断結果表示 |

## 機能種別

診断処理 / ヘルスチェック / トラブルシューティング支援

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| なし | - | - | 引数なしで実行 | - |

### 入力データソース

- システム環境（PATH, 環境変数）
- Emacsの機能フラグ（featurep）
- gitコマンド出力
- fontconfigの出力
- 各モジュールのdoctor.elファイル

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 成功メッセージ | 文字列 | 緑色でチェック通過を表示 |
| 警告メッセージ | 文字列 | 黄色で潜在的問題を表示 |
| エラーメッセージ | 文字列 | 赤色で重大な問題を表示 |
| 説明テキスト | 文字列 | 問題の詳細と解決策を表示 |

### 出力先

- 標準出力: 診断結果メッセージ
- 終了コード: 問題数に応じた終了ステータス

## 処理フロー

### 処理シーケンス

```
1. Emacsバージョンチェック
   └─ 開発版（>30, .50/.60/.9x）の検出と警告
   └─ Emacs 27の非推奨警告
   └─ emacs-pgtk 29.4のセグフォルト警告

2. 前提条件チェック
   └─ gitの存在確認とバージョンチェック（2.23以上必須）
   └─ rgの存在確認（必須依存）

3. Emacs設定競合チェック
   └─ 非標準インストール場所の検出
   └─ 競合する設定ファイルの検出（~/.emacs等）

4. Emacs機能チェック
   └─ ネイティブJSON（jansson）サポート確認
   └─ ネイティブコンパイルサポート確認

5. フォント環境チェック
   └─ fc-listコマンドの存在確認
   └─ Symbolaフォントの検出

6. プライベート設定チェック
   └─ DOOMDIRとdoom-emacs-dirの競合検出
   └─ 複数プライベート設定ディレクトリの検出

7. 環境問題チェック
   └─ 一時ファイルディレクトリの書き込み権限
   └─ 非POSIXシェルの検出
   └─ シンボリックリンクサポート（Windows）

8. 古いelcファイルチェック
   └─ doom-core-dir配下のelcファイル
   └─ doom-modules-dir配下のelcファイル
   └─ straight build配下のelcファイル

9. Git設定チェック
   └─ insteadOf設定の検出

10. Doom初期化とモジュールチェック
    └─ doom-initializeとdoom-startup
    └─ キャッシュファイルサイズチェック（savehist等）
    └─ fdコマンド存在確認
    └─ $HOMEがプロジェクトルートでないか確認
    └─ nerd-iconsフォント確認
    └─ 各モジュールのdoctor.el実行

11. 最終レポート
    └─ 警告数とエラー数の集計表示
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[Emacsバージョンチェック]
    B --> C{開発版?}
    C -->|Yes| D[警告表示]
    C -->|No| E{v27?}
    D --> E
    E -->|Yes| F[非推奨警告]
    E -->|No| G[前提条件チェック]
    F --> G
    G --> H{git存在?}
    H -->|No| I[エラー表示]
    H -->|Yes| J{gitバージョン>=2.23?}
    I --> K[rg確認]
    J -->|No| L[エラー表示]
    J -->|Yes| K
    L --> K
    K --> M[設定競合チェック]
    M --> N[Emacs機能チェック]
    N --> O[フォント確認]
    O --> P[プライベート設定チェック]
    P --> Q[環境問題チェック]
    Q --> R[古いelcチェック]
    R --> S[Git設定チェック]
    S --> T[Doom初期化]
    T --> U{成功?}
    U -->|Yes| V[モジュール診断]
    U -->|No| W[エラー表示]
    V --> X[最終レポート]
    W --> X
    X --> Y[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | Git最低バージョン | Git 2.23以上が必須 | gitコマンド実行時 |
| BR-02 | rg必須依存 | ripgrepが必須 | ファイル検索機能使用時 |
| BR-03 | 開発版Emacs警告 | バージョンが.50/.60/.9xで終わる場合警告 | Emacsバージョンチェック時 |
| BR-04 | Emacs27非推奨 | 2025年中頃にサポート終了予定 | emacs-major-version = 27 |
| BR-05 | キャッシュサイズ制限 | 1MB超のキャッシュファイルは警告 | savehist, projectile.cache |

### 計算ロジック

**Emacsバージョン判定**:
```elisp
;; 開発版検出
(or (> emacs-major-version 30)
    (string-match-p ".\\([56]0\\|9[0-9]\\)$" emacs-version))
```

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 警告 | gitが古いバージョン | gitをアップグレード |
| - | エラー | gitが存在しない | gitをインストール |
| - | エラー | rgが存在しない | ripgrepをインストール |
| - | 警告 | 設定ファイル競合 | 重複設定を削除 |
| - | 警告 | フォント不足 | 推奨フォントをインストール |

### リトライ仕様

診断コマンドのため、リトライ機構は不要。

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

読み取り専用の診断処理のため、トランザクション管理は不要。

## パフォーマンス要件

- 診断処理は通常数秒で完了
- モジュール数が多い場合、各doctor.elの実行に時間がかかる可能性

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

- 診断結果に機密情報（パス情報等）が含まれる可能性があるため、issue報告時は注意

## 備考

- 診断結果の最後に"+G"オプションでページャーを使用（末尾にジャンプ）
- ベンチマーク計測は無効（:benchmark nil）

---

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

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

### 推奨読解順序

#### Step 1: DSLマクロを理解する

診断処理で使用されるDSLマクロを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | doctor.el | `lisp/cli/doctor.el` | 5-37行目のDSLマクロ定義 |

**読解のコツ**: `error!`, `warn!`, `success!`, `section!`, `explain!`, `assert!`マクロは診断結果の出力形式を統一するためのDSL。各マクロは`print!`マクロを内部で使用し、色付きの出力を生成する。

**主要処理フロー**:
- **5-6行目**: doom-doctor--warnings, doom-doctor--errors変数定義
- **12-16行目**: elc-check-dir関数（古いelcファイル検出）
- **18-20行目**: assert!マクロ
- **22-24行目**: error!マクロ（エラー追加と表示）
- **26-28行目**: warn!マクロ（警告追加と表示）

#### Step 2: メインコマンド定義を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | doctor.el | `lisp/cli/doctor.el` | 43-51行目のdefcli!定義 |

**主要処理フロー**:
- **43行目**: `(defcli! ((doctor doc)) ()` - doctorコマンド定義（docもエイリアス）
- **52行目**: `:benchmark nil` - ベンチマーク無効化

#### Step 3: 各診断処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | doctor.el | `lisp/cli/doctor.el` | 55-85行目 Emacsバージョンチェック |
| 3-2 | doctor.el | `lisp/cli/doctor.el` | 87-104行目 前提条件チェック |
| 3-3 | doctor.el | `lisp/cli/doctor.el` | 106-130行目 設定競合チェック |
| 3-4 | doctor.el | `lisp/cli/doctor.el` | 132-145行目 Emacs機能チェック |

**主要処理フロー**:
- **57-79行目**: Emacsバージョン判定ロジック
- **89-104行目**: git/rgの存在確認
- **108-130行目**: ~/.emacs等の競合検出
- **134-145行目**: json-serialize, native-compileの確認

#### Step 4: モジュール診断処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | doctor.el | `lisp/cli/doctor.el` | 328-366行目 モジュール診断ループ |

**主要処理フロー**:
- **330行目**: doom-module-listでモジュール一覧取得
- **338-339行目**: doctor.elとpackages.elのパス取得
- **354-356行目**: doctor.elの読み込みと実行

#### Step 5: 最終レポート処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | doctor.el | `lisp/cli/doctor.el` | 373-384行目 最終レポート |

**主要処理フロー**:
- **374-381行目**: 警告・エラー数の集計と表示
- **382-383行目**: 問題なしの場合の成功メッセージ
- **384行目**: exit!でページャー起動

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

```
doom doctor (defcli!)
    │
    ├─ Emacsバージョンチェック
    │      └─ emacs-major-version, emacs-version
    │
    ├─ 前提条件チェック
    │      ├─ executable-find "git"
    │      │      └─ doom-call-process "git" "version"
    │      └─ executable-find "rg"
    │
    ├─ 設定競合チェック
    │      └─ file-exists-p, file-equal-p
    │
    ├─ Emacs機能チェック
    │      ├─ functionp 'json-serialize
    │      └─ featurep 'native-compile
    │
    ├─ フォント確認
    │      └─ doom-call-process "fc-list"
    │
    ├─ 環境チェック
    │      ├─ file-writable-p temporary-file-directory
    │      └─ doom-system-supports-symlinks-p
    │
    ├─ elcファイルチェック
    │      └─ elc-check-dir
    │
    ├─ Git設定チェック
    │      └─ doom-call-process "git" "config"
    │
    ├─ Doom初期化
    │      ├─ doom-initialize
    │      └─ doom-startup
    │
    └─ モジュール診断
           ├─ doom-module-list
           └─ load doctor.el (各モジュール)
```

### データフロー図

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

システム環境        ───▶  バージョン確認  ───▶  警告/エラーリスト
(PATH, env)                    │
                               │
Emacsビルト         ───▶  機能確認      ───▶  doom-doctor--warnings
イン機能                       │                doom-doctor--errors
                               │
各モジュール        ───▶  doctor.el    ───▶  モジュール固有の
doctor.el                 実行              診断結果
                               │
                               │
                          集計処理      ───▶  最終レポート
                                              (警告数/エラー数)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| doctor.el | `lisp/cli/doctor.el` | ソース | doctorコマンドの主実装 |
| doom-cli.el | `lisp/doom-cli.el` | ソース | CLIフレームワーク |
| doom.el | `lisp/doom.el` | ソース | Doomコア（doom-initialize） |
| doom-start.el | `lisp/doom-start.el` | ソース | 起動処理（doom-startup） |
| 各モジュールのdoctor.el | `modules/*/*/doctor.el` | ソース | モジュール固有の診断 |
