# 機能設計書 38-ディスク使用量

## 概要

本ドキュメントは、Nushellにおけるディスク使用量取得機能（du）の設計を記述する。このコマンドはファイルやディレクトリのディスク使用量を計算して表示する。

### 本機能の処理概要

**業務上の目的・背景**：
ディスク使用量の把握は、ストレージ管理、不要ファイルの特定、プロジェクトサイズの把握など多くの場面で必要とされる。Nushellのduコマンドは、Unix系のduコマンドと同様の機能を提供しつつ、構造化データとして出力することでフィルタリングやソートを容易にする。

**機能の利用シーン**：
- プロジェクトのディスク使用量の確認
- 大きなファイル/ディレクトリの特定
- ディスク空き容量の管理
- バックアップサイズの見積もり

**主要な処理内容**：
1. 指定されたパスのディスク使用量を計算
2. 見かけのサイズと実際のディスク使用量（ブロックサイズ）を表示
3. 再帰的なディレクトリサイズの計算
4. フィルタリングオプション（最小サイズ、除外パターン等）

**関連システム・外部連携**：
- filesize クレート（実際のディスク使用量計算）
- nu-glob クレート（globパターンマッチング）

**権限による制御**：
- 対象ファイル/ディレクトリへの読み取り権限が必要

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | メインREPL | 参照画面 | コマンド入力・結果表示 |

## 機能種別

ファイルシステム情報取得

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| path | GlobPattern/String | No | 対象パス（デフォルトは*） | 有効なパス/globパターン |
| --deref | Switch | No | シンボリックリンクを解決 | - |
| --long | Switch | No | 詳細情報を表示（サブディレクトリ/ファイル含む） | - |
| --all | Switch | No | 隠しファイルを含める | - |
| --exclude | GlobPattern | No | 除外するファイルパターン | 有効なglobパターン |
| --max-depth | Int | No | 再帰の最大深度 | 正の整数 |
| --min-size | Int | No | 最小ファイルサイズ | 正の整数 |

### 入力データソース

コマンドライン引数

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| path | String | ファイル/ディレクトリのパス |
| apparent | Filesize | 見かけのファイルサイズ |
| physical | Filesize | 実際のディスク使用量 |
| directories | List | サブディレクトリ一覧（--long時） |
| files | List | ファイル一覧（--long時） |

### 出力先

パイプライン出力（テーブル形式）

## 処理フロー

### 処理シーケンス

```
1. オプションの解析
   └─ max-depth, min-sizeの妥当性検証
2. パスの取得
   └─ 未指定の場合は * パターン
3. globパターンの展開
   └─ マッチするファイル/ディレクトリを取得
4. 各パスについてサイズ計算
   └─ ディレクトリの場合はDirInfo、ファイルの場合はFileInfo
5. 結果の返却
   └─ テーブル形式で出力
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{max-depth/min-size検証}
    B -->|無効| C[NeedsPositiveValueエラー]
    B -->|有効| D{パス指定?}
    D -->|No| E[*パターンを使用]
    D -->|Yes| F[指定パターンを使用]
    E --> G[glob展開]
    F --> G
    G --> H[各パスを処理]
    H --> I{ディレクトリ?}
    I -->|Yes| J[DirInfo::new]
    I -->|No| K[FileInfo::new]
    J --> L[サイズ集計]
    K --> L
    L --> M[Value変換]
    M --> N{次のパス?}
    N -->|Yes| H
    N -->|No| O[テーブル出力]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-38-1 | 見かけサイズ | ファイルの論理サイズを表示 | 常に |
| BR-38-2 | 物理サイズ | 実際のディスクブロック使用量を表示 | 常に |
| BR-38-3 | 再帰計算 | ディレクトリ内のすべてのファイルを合計 | ディレクトリ指定時 |
| BR-38-4 | 深度制限 | max-depthで指定した深さまで計算 | --max-depth指定時 |
| BR-38-5 | サイズフィルタ | min-size未満のファイルを除外 | --min-size指定時 |
| BR-38-6 | 除外パターン | 指定パターンにマッチするファイルを除外 | --exclude指定時 |

### 計算ロジック

- 見かけのサイズ: `std::fs::metadata().len()`
- 物理サイズ: `filesize::file_real_size_fast()`
- ディレクトリサイズ: 含まれるすべてのファイル/サブディレクトリのサイズの合計

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

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

該当なし（ファイルシステム操作のみ）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| NeedsPositiveValue | 引数エラー | max-depthが負の値 | 正の値を指定 |
| NeedsPositiveValue | 引数エラー | min-sizeが負の値 | 正の値を指定 |
| InvalidGlobPattern | パターンエラー | 無効なglobパターン | 正しいパターンを使用 |
| IOエラー | ファイルエラー | ファイルアクセス失敗 | 権限を確認 |

### リトライ仕様

該当なし

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

該当なし

## パフォーマンス要件

- ディレクトリごとに再帰的に処理
- Signals.check()で中断可能
- 大規模ディレクトリでもストリーミング処理で低メモリ消費

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

- 対象パスへの読み取り権限が必要
- シンボリックリンクの追跡はオプション（--deref）

## 備考

- apparentとphysicalの違い: スパースファイルや圧縮ファイルシステムでは異なる値になる
- --longオプションで詳細な内訳を確認可能
- PipelineMetadataにpath_columnsを設定

---

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

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

### 推奨読解順序

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

DirInfo、FileInfo、DirBuilderの構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | dir_info.rs | `crates/nu-command/src/platform/dir_info.rs` | DirBuilder構造体（6-13行目） |
| 1-2 | dir_info.rs | `crates/nu-command/src/platform/dir_info.rs` | DirInfo構造体（33-43行目） |
| 1-3 | dir_info.rs | `crates/nu-command/src/platform/dir_info.rs` | FileInfo構造体（45-52行目） |

**読解のコツ**: DirInfoはdirs（サブディレクトリ）とfiles（ファイル）を持つ再帰的な構造。sizeとblocksは見かけのサイズと物理サイズ。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | du.rs | `crates/nu-command/src/filesystem/du.rs` | Duコマンドの実装 |

**主要処理フロー**:
1. **74-102行目**: run関数でオプション解析
2. **111-133行目**: パスなしの場合（*パターン）
3. **134-167行目**: パスありの場合（複数パターン対応）

#### Step 3: サイズ計算ロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | dir_info.rs | `crates/nu-command/src/platform/dir_info.rs` | DirInfo::new関数（86-135行目） |
| 3-2 | dir_info.rs | `crates/nu-command/src/platform/dir_info.rs` | FileInfo::new関数（54-83行目） |

**主要処理フロー**:
- **107-113行目**: ディレクトリエントリのサイズ取得
- **115-133行目**: 子要素の処理（add_dir/add_file）
- **70行目**: file_real_size_fast()で物理サイズ取得

#### Step 4: Value変換を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | dir_info.rs | `crates/nu-command/src/platform/dir_info.rs` | From<DirInfo>実装（191-229行目） |
| 4-2 | dir_info.rs | `crates/nu-command/src/platform/dir_info.rs` | From<FileInfo>実装（231-258行目） |

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

```
Du::run()
    │
    ├─ call.get_flag() [オプション取得]
    │
    ├─ call.rest() [パス引数取得]
    │
    └─ du_for_one_pattern()
           │
           ├─ Pattern::new() [除外パターン]
           │
           ├─ nu_engine::glob_from() [glob展開]
           │
           └─ [各パスを処理]
                  │
                  ├─ [ディレクトリ] → DirInfo::new()
                  │                       │
                  │                       ├─ add_dir() [再帰]
                  │                       │
                  │                       └─ add_file()
                  │
                  └─ [ファイル] → FileInfo::new()
                                      │
                                      └─ file_real_size_fast()
```

### データフロー図

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

パス/パターン ───▶ Du::run() ─────────▶ Table
    │                  │
    │                  ├─ glob展開
    │                  │
    │                  ├─ サイズ計算
    │                  │      │
    │                  │      ├─ apparent (論理)
    │                  │      │
    │                  │      └─ physical (物理)
    │                  │
    │                  └─ Value変換
    │
オプション ────────────┘
(--long, --exclude等)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| du.rs | `crates/nu-command/src/filesystem/du.rs` | ソース | du コマンド実装 |
| dir_info.rs | `crates/nu-command/src/platform/dir_info.rs` | ソース | DirInfo/FileInfo構造体 |
| mod.rs | `crates/nu-command/src/filesystem/mod.rs` | ソース | filesystemモジュール定義 |
