# 通知設計書 109-hintExecuting

## 概要

本ドキュメントは、Nimコンパイラの`hintExecuting`ヒント通知に関する設計を定義する。このヒントは、外部プログラムの実行を通知するものである。

### 本通知の処理概要

`hintExecuting`ヒントは、Nimコンパイラが外部プログラム（Cコンパイラ、外部コマンドなど）を実行する際に、その実行コマンドを開発者に通知するヒントメッセージである。

**業務上の目的・背景**：Nimコンパイラはコンパイルプロセスの一部として、Cコンパイラ呼び出し、nifmakeなどのビルドツール実行、ドキュメント生成ツール呼び出しなど、様々な外部プログラムを実行する。この通知により、開発者は実際に実行されるコマンドを確認でき、ビルドプロセスのデバッグや、外部ツールの問題特定に役立てることができる。

**通知の送信タイミング**：外部プログラムを実行する直前に送信される。具体的には`execWithEcho`関数、`execExternalProgram`関数、その他の外部コマンド実行箇所で出力される。

**通知の受信者**：コンパイル実行者（開発者）がコンソール出力（stderr）を通じてこの通知を受信する。

**通知内容の概要**：「$1」という形式で、実行されるコマンド文字列全体が表示される。

**期待されるアクション**：開発者はこの通知を確認し、実行されるコマンドが期待通りかどうか検証する。コマンドが失敗した場合、表示されたコマンドを手動で実行してデバッグできる。

## 通知種別

コンソール出力（コンパイラヒント）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（コンパイルプロセス内で即時出力） |
| 優先度 | 低（ヒント情報） |
| リトライ | 無し |

### 送信先決定ロジック

標準エラー出力（stderr）に送信される。`--stdout`オプションが指定されている場合は標準出力（stdout）に送信される。`writelnHook`が設定されている場合は、そのフック関数に委譲される。

## 通知テンプレート

### コンソール出力の場合

| 項目 | 内容 |
|-----|------|
| メッセージ種別 | Hint |
| フォーマット | `Hint: {コマンド} [Exec]` |
| 色 | 緑色（HintColor = fgGreen） |

### 本文テンプレート

```
Hint: nifmake run /path/to/build.json [Exec]
```

### 添付ファイル

なし

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| $1 | 実行コマンド | 外部プログラム呼び出し時のコマンド文字列 | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| コンパイル処理 | 外部プログラム実行 | デフォルト | execWithEcho, execExternalProgram呼び出し時 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| optHints not in conf.options | ヒント出力自体が無効化されている場合 |
| hintExecuting not in conf.notes | 個別にヒントが無効 |
| verbosity = 0 | NotesVerbosity[0]から除外 |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[外部プログラム実行要求] --> B[execWithEcho / execExternalProgram]
    B --> C[rawMessage hintExecuting]
    C --> D[liMessage処理]
    D --> E{hintExecuting有効?}
    E -->|No| F[出力スキップ]
    E -->|Yes| G[styledMsgWriteln]
    G --> H[コマンド実行: execCmd]
    F --> H
    H --> I{終了コード確認}
    I -->|成功| J[次の処理へ]
    I -->|失敗| K[エラー処理]
```

## データベース参照・更新仕様

該当なし（ファイルシステムやデータベースへのアクセスなし）

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| 該当なし | このヒントは情報出力のみ | - |
| 外部プログラム失敗 | execCmd != 0 | errGenerated出力 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 0（リトライなし） |
| リトライ間隔 | - |
| リトライ対象エラー | - |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 制限なし | 外部プログラム実行ごとに出力 |

### 配信時間帯

制限なし（コンパイル実行時に即時出力）

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

- 実行コマンドがログに出力されるため、パスやオプションに機密情報が含まれる可能性
- CI/CDログに出力される場合、システム構成情報が漏洩する可能性に注意

## 備考

- verbosity 1以上または`--hint:Exec:on`オプションで有効化可能（デフォルトでは無効）
- 外部パッケージでも出力される（foreignPackageNotesDefaultに含まれる）
- Cコンパイラ呼び出し時はhintCC（No.91）が使用される場合もある
- リンク時はhintLinking（No.110）が使用される

---

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

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

### 推奨読解順序

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

通知種別の定義を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | lineinfos.nim | `compiler/lineinfos.nim` | TMsgKind列挙型でhintExecutingの定義を確認（111行目） |
| 1-2 | lineinfos.nim | `compiler/lineinfos.nim` | MsgKindToStr配列でメッセージ文字列を確認（232行目） |
| 1-3 | lineinfos.nim | `compiler/lineinfos.nim` | NotesVerbosity[0]からhintExecutingが除外されていることを確認（271行目） |

**読解のコツ**: hintExecutingは"Exec"という短縮名を持ち、出力時には[Exec]として表示される。

#### Step 2: 外部プログラム実行処理を理解する

外部プログラム実行の核心部分を特定。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | extccomp.nim | `compiler/extccomp.nim` | execWithEcho関数（430-432行目）でヒント出力処理を確認 |
| 2-2 | extccomp.nim | `compiler/extccomp.nim` | execExternalProgram関数（434-437行目）で外部プログラム実行を確認 |

**主要処理フロー**:
1. **430行目**: `execWithEcho`関数定義
2. **431行目**: `rawMessage(conf, msg, ...)`でhintExecutingを出力
3. **432行目**: `execCmd(cmd)`で実際のコマンド実行
4. **434-437行目**: `execExternalProgram`関数でexecWithEchoを呼び出し

#### Step 3: 他の使用箇所を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | deps.nim | `compiler/deps.nim` | nifmake実行時のhintExecuting使用（390行目） |
| 3-2 | docgen.nim | `compiler/docgen.nim` | ドキュメント生成時の外部コマンド実行（415行目） |

**主要処理フロー**:
- **deps.nim 390行目**: `rawMessage(conf, hintExecuting, cmd)`でnifmakeコマンドを表示

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

```
callCCompiler (extccomp.nim)
    │
    ├─ execCmdsInParallel
    │      └─ execWithEcho
    │             │
    │             ├─ rawMessage(hintExecuting) ← ここでhintExecuting出力
    │             │      └─ liMessage → styledMsgWriteln
    │             │
    │             └─ execCmd(cmd)
    │
    └─ execLinkCmd
           └─ execExternalProgram(hintLinking) ← リンク時はhintLinking

deps.nim: compileToDep
    │
    └─ rawMessage(hintExecuting) ← nifmake実行時

docgen.nim: renderRstToOut
    │
    └─ rawMessage(hintExecuting) ← ドキュメント生成時
```

### データフロー図

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

コマンド文字列   ───▶ execWithEcho         ───▶ stderr/stdout
                       │                      "Hint: {command}"
                       ▼
                  rawMessage(hintExecuting)
                       │
                       ▼
                  execCmd                  ───▶ 外部プログラム実行
                       │
                       ▼
                  終了コード               ───▶ 成功/失敗判定
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| lineinfos.nim | `compiler/lineinfos.nim` | ソース | メッセージ種別定義（TMsgKind列挙型） |
| extccomp.nim | `compiler/extccomp.nim` | ソース | execWithEcho, execExternalProgram関数 |
| deps.nim | `compiler/deps.nim` | ソース | nifmake実行時のhintExecuting使用 |
| docgen.nim | `compiler/docgen.nim` | ソース | ドキュメント生成時のhintExecuting使用 |
| msgs.nim | `compiler/msgs.nim` | ソース | rawMessage関数、メッセージ出力処理 |
| options.nim | `compiler/options.nim` | ソース | foreignPackageNotesDefault（hintExecuting含む） |
