# 機能設計書 56-環境変数

## 概要

本ドキュメントは、Nushellにおける環境変数管理機能の設計仕様を記載する。この機能は、load-env、with-env、config envなどのコマンドを通じて環境変数の設定・参照・一時的な変更を提供する。

### 本機能の処理概要

環境変数管理機能は、Nushellセッション内での環境変数の操作を行う。スタックベースのスコープ管理により、一時的な環境変数設定や階層的な環境管理を実現する。

**業務上の目的・背景**：シェルスクリプトや開発環境において、環境変数は設定情報やパス情報の管理に不可欠である。Nushellでは構造化データとして環境変数を扱い、レコード形式での一括設定やスコープ付き環境変数設定をサポートする。

**機能の利用シーン**：
- 開発環境ごとの環境変数設定
- 外部コマンド実行時の一時的な環境変数変更
- 設定ファイル(env.nu)からの環境変数ロード
- APIキーやデータベース接続情報の管理
- パス設定（PATH, LD_LIBRARY_PATH等）

**主要な処理内容**：
1. load-envでレコードから複数の環境変数を一括設定
2. with-envでブロック実行中のみ有効な環境変数設定
3. config envで環境設定ファイルの編集
4. $env変数を通じた環境変数へのアクセス

**関連システム・外部連携**：
- オペレーティングシステムの環境変数
- 外部コマンド実行（環境変数の継承）
- 設定ファイル（env.nu）

**権限による制御**：特になし（ユーザー権限内で動作）

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | メインREPL | 補助機能 | REPL実行中の環境変数管理（CMD_DURATION_MS等） |

## 機能種別

環境設定 / スコープ管理

## 入力仕様

### 入力パラメータ

#### load-env

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| update | Record | No（パイプライン入力可） | 環境変数のレコード | FILE_PWD, CURRENT_FILE, PWDは設定不可 |

#### with-env

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| variable | Record | Yes | 一時的に設定する環境変数 | PWD, FILE_PWD, CURRENT_FILEは設定不可 |
| block | Closure | Yes | 環境変数設定下で実行するブロック | - |

### 入力データソース

コマンドライン引数、パイプライン入力（レコード形式）

## 出力仕様

### 出力データ

#### load-env

| 項目名 | 型 | 説明 |
|--------|-----|------|
| (出力) | Nothing | 成功時は出力なし |

#### with-env

| 項目名 | 型 | 説明 |
|--------|-----|------|
| (出力) | Any | ブロックの実行結果 |

### 出力先

パイプライン出力

## 処理フロー

### 処理シーケンス（load-env）

```
1. 入力取得
   └─ 引数またはパイプラインからレコードを取得
2. 禁止変数チェック
   └─ FILE_PWD, CURRENT_FILE, PWDの設定を拒否
3. 環境変数設定
   └─ stack.add_env_var()で各変数を追加
4. 結果返却
   └─ PipelineData::empty()を返却
```

### 処理シーケンス（with-env）

```
1. 引数取得
   └─ 環境変数レコードとクロージャを取得
2. 禁止変数チェック
   └─ PWD, FILE_PWD, CURRENT_FILEの設定を拒否
3. スタック分離
   └─ captures_to_stack_preserve_out_dest()で新スタック作成
4. 環境変数設定
   └─ 新スタックに環境変数を追加
5. ブロック実行
   └─ eval_block()でクロージャを実行
6. 結果返却
   └─ ブロックの実行結果を返却
```

### フローチャート

```mermaid
flowchart TD
    A[load-env実行] --> B{入力ソース}
    B -->|引数| C[引数からレコード取得]
    B -->|パイプライン| D[パイプラインからレコード取得]
    C --> E[禁止変数チェック]
    D --> E
    E --> F{禁止変数あり?}
    F -->|Yes| G[AutomaticEnvVarSetManuallyエラー]
    F -->|No| H[各変数をスタックに追加]
    H --> I[Nothing返却]

    J[with-env実行] --> K[引数取得]
    K --> L[禁止変数チェック]
    L --> M{禁止変数あり?}
    M -->|Yes| N[AutomaticEnvVarSetManuallyエラー]
    M -->|No| O[新スタック作成]
    O --> P[環境変数追加]
    P --> Q[ブロック実行]
    Q --> R[結果返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 自動変数保護 | FILE_PWD, CURRENT_FILE, PWDは手動設定不可 | load-env, with-env |
| BR-02 | スコープ限定 | with-envの変数はブロック終了で破棄 | with-env |
| BR-03 | パイプライン優先 | 引数なしの場合はパイプライン入力を使用 | load-env |
| BR-04 | 値の保持 | with-env実行後も元の環境変数は保持 | with-env |

### 計算ロジック

特になし

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

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| AutomaticEnvVarSetManually | 操作エラー | 禁止変数の設定試行 | 他の変数名を使用 |
| UnsupportedInput | 入力エラー | レコード以外の入力 | レコード形式で入力 |

### リトライ仕様

該当なし

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

該当なし

## パフォーマンス要件

特になし（即座に完了）

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

- 機密情報（APIキー、パスワード等）は環境変数として設定可能だが、ログ出力やエラーメッセージに含まれる可能性あり
- 外部コマンド実行時に環境変数が継承されることを考慮

## 備考

- $env変数を通じて直接環境変数にアクセス可能
- config envでenv.nuファイルを編集可能

---

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

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

### 推奨読解順序

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

環境変数はスタック上のHashMap<String, Value>として管理される。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | load_env.rs | `crates/nu-command/src/env/load_env.rs` | 入力レコード構造の確認 |

**読解のコツ**:
- **15-30行目**: シグネチャでRecord型の入力を定義

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | load_env.rs | `crates/nu-command/src/env/load_env.rs` | load-envコマンドの実装 |
| 2-2 | with_env.rs | `crates/nu-command/src/env/with_env.rs` | with-envコマンドの実装 |

**主要処理フロー（load_env.rs）**:
- **33-56行目**: run()で引数またはパイプラインからレコード取得
- **58-65行目**: 禁止変数のチェック
- **67-69行目**: 各環境変数をスタックに追加

**主要処理フロー（with_env.rs）**:
- **54-61行目**: with_env()で引数取得
- **66-73行目**: 禁止変数のチェック
- **75-77行目**: 環境変数を新スタックに追加
- **79行目**: eval_block()でブロック実行

#### Step 3: スタック管理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | with_env.rs | `crates/nu-command/src/env/with_env.rs` | スタック分離の仕組み |

**主要処理フロー**:
- **63行目**: captures_to_stack_preserve_out_dest()でスタック分離

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

```
load-env コマンド
    │
    └─ run()
           │
           ├─ 引数 or パイプライン入力からRecord取得
           │
           ├─ 禁止変数チェック
           │      └─ FILE_PWD, CURRENT_FILE, PWD
           │
           └─ stack.add_env_var()
                  └─ 各変数をスタックに追加

with-env コマンド
    │
    └─ with_env()
           │
           ├─ 引数からRecord, Closure取得
           │
           ├─ 禁止変数チェック
           │      └─ PWD, FILE_PWD, CURRENT_FILE
           │
           ├─ stack.captures_to_stack_preserve_out_dest()
           │      └─ 新スタック作成
           │
           ├─ stack.add_env_var()
           │      └─ 環境変数設定
           │
           └─ eval_block::<WithoutDebug>()
                  └─ ブロック実行
```

### データフロー図

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

Record {A: 1, B: 2} ───▶ load-env ─────────────────────▶ Nothing
                         stack.add_env_var()              (環境変数設定済み)

Record + Closure ───────▶ with-env ────────────────────▶ Any (ブロック結果)
                         新スタック作成
                         環境変数設定
                         ブロック実行
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| mod.rs | `crates/nu-command/src/env/mod.rs` | ソース | モジュール定義 |
| load_env.rs | `crates/nu-command/src/env/load_env.rs` | ソース | load-envコマンド |
| with_env.rs | `crates/nu-command/src/env/with_env.rs` | ソース | with-envコマンド |
| export_env.rs | `crates/nu-command/src/env/export_env.rs` | ソース | export-envコマンド |
| source_env.rs | `crates/nu-command/src/env/source_env.rs` | ソース | source-envコマンド |
| config_env.rs | `crates/nu-command/src/env/config/config_env.rs` | ソース | config envコマンド |
