# 機能設計書 80-診断出力

## 概要

本ドキュメントは、clojure-lsp の CLI コマンドとして提供される `diagnostics` コマンドの機能設計を記述する。このコマンドはプロジェクト内の全ての診断情報（警告、エラー、情報）を取得し、コマンドラインに出力する機能を提供する。

### 本機能の処理概要

**業務上の目的・背景**：CI/CD パイプラインでコード品質をチェックする際、LSP サーバーを起動せずに診断情報を取得する必要がある。この機能はコマンドラインから直接診断を実行し、結果を標準出力に出力することで、自動化パイプラインへの統合を容易にする。

**機能の利用シーン**：CI/CD パイプラインでの lint チェック、プルリクエスト時の自動コード品質チェック、コードレビュー支援などで利用される。

**主要な処理内容**：
1. プロジェクトの解析
2. 対象名前空間/ファイルの特定
3. 診断情報の収集
4. 結果の出力（テキスト/EDN/JSON）

**関連システム・外部連携**：clj-kondo（静的解析）、CI/CD ツール（結果の消費側）。

**権限による制御**：呼び出し元プロセスのファイルシステム権限に依存。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 該当なし | 該当なし | 該当なし | 本プロジェクトは LSP サーバー実装であり UI 画面は存在しない |

## 機能種別

データ取得 / レポート出力

## 入力仕様

### 入力パラメータ（CLI オプション）

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| --project-root / -p | File | No | プロジェクトルートのパス | 存在するディレクトリ |
| --namespace / -n | Symbol | No | 対象名前空間（複数指定可） | 有効なシンボル |
| --filenames | String | No | 対象ファイル（カンマまたはコロン区切り） | 有効なファイルパス |
| --ns-exclude-regex | Regex | No | 除外する名前空間の正規表現 | 有効な正規表現 |
| --output / -o | EDN | No | 出力設定 | :canonical-paths, :format |
| --raw | Boolean | No | 最小限の出力 | - |
| --settings / -s | EDN | No | 設定を EDN 形式で指定 | 有効な EDN マップ |

### 入力データソース

- ファイルシステム（プロジェクトソースファイル）
- clj-kondo 解析結果
- カスタム linter 結果

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 終了コード | Integer | 0: 診断なし/情報のみ、2: 警告あり、3: エラーあり |

### 出力形式

- デフォルト: テキスト形式（ファイル:行:列: レベル: [コード] メッセージ）
- --output {:format :edn}: EDN 形式
- --output {:format :json}: JSON 形式

### 出力先

- 標準出力（診断情報）
- 標準エラー出力（進捗情報、--raw でなければ）
- プロセス終了コード

## 処理フロー

### 処理シーケンス

```
1. CLI オプション解析
2. プロジェクト解析
   └─ project-and-shallow-analysis で解析
3. 対象 URI の特定
   └─ namespace/filenames から URI リストを生成
4. 診断の取得
   └─ 各 URI に対して find-diagnostics 実行
5. 結果の出力
   └─ format に応じて出力形式を選択
6. 終了コード決定
   └─ severity に基づいて終了コードを決定
```

### フローチャート

```mermaid
flowchart TD
    A[clojure-lsp diagnostics] --> B[CLI オプション解析]
    B --> C[プロジェクト解析]
    C --> D[対象 URI 特定]
    D --> E[各 URI の診断取得]
    E --> F{診断あり?}
    F -->|No| G[No diagnostics found!]
    F -->|Yes| H[結果出力]
    G --> I[終了コード 0]
    H --> J{エラーあり?}
    J -->|Yes| K[終了コード 3]
    J -->|No| L{警告あり?}
    L -->|Yes| M[終了コード 2]
    L -->|No| I
    I --> N[終了]
    K --> N
    M --> N
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-80-1 | 終了コード決定 | エラー: 3、警告: 2、情報のみ/なし: 0 | 常時 |
| BR-80-2 | 出力形式選択 | --output {:format :edn/:json} で形式変更可能 | --output 指定時 |
| BR-80-3 | パス形式 | --output {:canonical-paths true} で絶対パス出力 | --output 指定時 |
| BR-80-4 | 除外フィルタ | --ns-exclude-regex にマッチする名前空間は除外 | --ns-exclude-regex 指定時 |

### 計算ロジック

終了コード：
- 3: severity 1 (error) が1つ以上存在
- 2: severity 2 (warning) が1つ以上存在（error なし）
- 0: severity 3 以上（info, hint）のみ、または診断なし

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 該当なし | 該当なし | 該当なし | RDB は使用しない |

### テーブル別操作詳細

atom によるインメモリデータベースを参照。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 該当なし | 解析エラー | プロジェクト解析に失敗 | エラーログを確認 |

### リトライ仕様

リトライ機構は実装されていない。

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

RDB を使用しないため、トランザクション管理は不要。

## パフォーマンス要件

- pmap による並列処理で高速化
- プロジェクトサイズに依存

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

- ファイルシステムアクセスはプロセス権限に依存

## 備考

- API 版は `clojure-lsp.api/diagnostics` として提供
- CI/CD での利用を主目的として設計

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | diagnostics.clj | `lib/src/clojure_lsp/feature/diagnostics.clj` | 診断データ構造 |

**読解のコツ**: Diagnostic 構造（:range, :message, :severity, :code）を理解する。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | main.clj | `cli/src/clojure_lsp/main.clj` | CLI エントリーポイント |

**主要処理フロー**:
1. **34行目**: diagnostics コマンド説明
2. **203行目**: handle-action! で "diagnostics" アクション処理

#### Step 3: 内部 API 実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | internal_api.clj | `lib/src/clojure_lsp/internal_api.clj` | diagnostics* の実装 |

**主要処理フロー**:
- **325-342行目**: diagnostics->diagnostic-messages で出力文字列生成
- **344-354行目**: diagnostics-by-uri で URI ごとの診断取得
- **355-372行目**: diagnostics* で結果コード決定と返却

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

```
main/-main
    |
    +-- main/run!
            |
            +-- parse
            |
            +-- handle-action! "diagnostics"
                    |
                    +-- internal-api/diagnostics
                            |
                            +-- build-components
                            |
                            +-- diagnostics*
                                    |
                                    +-- setup-api!
                                    +-- setup-project-and-clojure-only-deps-analysis!
                                    +-- diagnostics-by-uri
                                            |
                                            +-- options->uris
                                            +-- f.diagnostic/find-diagnostics
                                    +-- 終了コード決定
                                    +-- diagnostics->diagnostic-messages
```

### データフロー図

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

--namespace [...]        main "diagnostics"                  file:line:col: level: [code] msg
--filenames [...]        |                                   または
--output {:format ...}   v                                   EDN/JSON 形式
        |           diagnostics-by-uri                        |
        |                |                                    |
        +-------------> f.diagnostic/find-diagnostics         |
                        |                                     |
                        v                                     |
                   {uri: [diag1, diag2, ...]}                 |
                        |                                     |
                        v                                     |
                   format に応じて出力                         |
                        |                                     |
              +---------+---------+---------+                 |
              |         |         |         |                 |
              v         v         v         v                 |
           テキスト    EDN      JSON    終了コード ----------> プロセス終了
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| main.clj | `cli/src/clojure_lsp/main.clj` | ソース | CLI エントリーポイント |
| internal_api.clj | `lib/src/clojure_lsp/internal_api.clj` | ソース | 内部実装 |
| api.clj | `lib/src/clojure_lsp/api.clj` | ソース | 公開 API |
| diagnostics.clj | `lib/src/clojure_lsp/feature/diagnostics.clj` | ソース | 診断機能 |
