# 機能設計書: 58-distros（Linuxディストリビューション検出）

## 1. 概要

### 1.1 業務上の目的・背景

distrosモジュールは、Linuxディストリビューションの検出とOSのネイティブパッケージマネージャー情報の提供を行う。主な目的は、Nimbleパッケージが外部依存パッケージのインストールコマンドを適切に出力できるようにすることである。

### 1.2 機能の利用シーン

- Nimbleパッケージの外部依存関係管理
- クロスプラットフォームインストーラの作成
- ディストリビューション固有の処理分岐
- パッケージマネージャーコマンドの生成
- システム要件の自動検出

### 1.3 主要な処理内容

1. OS検出: `detectOs` - ディストリビューション/OS判定
2. 依存登録: `foreignDep`, `foreignCmd` - 外部依存パッケージの登録
3. コマンド生成: `foreignDepInstallCmd` - インストールコマンド取得
4. 依存出力: `echoForeignDeps` - 登録済み依存の出力

### 1.4 関連するデータ/ファイル

- `/etc/os-release` - Linuxディストリビューション情報
- `lsb_release -d` - LSB準拠ディストリビューション情報
- `uname -a` - カーネル/OS情報
- `hostnamectl` - systemd系の情報

### 1.5 バッチ/オンライン区分

オンライン（システム情報取得）

## 2. 関連画面

- インストーラ
- セットアップウィザード
- システム情報表示

## 3. 機能種別

- [x] データ操作
- [ ] 帳票出力
- [ ] 外部連携
- [ ] バッチ処理
- [x] リアルタイム処理

## 4. 入力仕様

### 4.1 detectOsテンプレートパラメータ

| 項目名 | 型 | 説明 | 必須 |
|--------|-----|------|------|
| d | Distribution | 検出対象のディストリビューション | Yes |

### 4.2 foreignDep関数パラメータ

| 項目名 | 型 | 説明 | 必須 |
|--------|-----|------|------|
| foreignPackageName | string | 外部パッケージ名 | Yes |

### 4.3 foreignCmd関数パラメータ

| 項目名 | 型 | 説明 | 必須 | デフォルト |
|--------|-----|------|------|-----------|
| cmd | string | 実行コマンド | Yes | - |
| requiresSudo | bool | sudo必要性 | No | false |

### 4.4 入力チェック仕様

特別な入力チェックは行わない。不正なディストリビューション名はコンパイル時にenum型で検出される。

## 5. 出力仕様

### 5.1 Distribution enum

約100種類のLinux/BSD/その他のOSを表す列挙型。

主要なエントリ:
- Windows, Posix, MacOSX, Linux
- Ubuntu, Debian, Fedora, CentOS, RedHat
- ArchLinux, Manjaro, Gentoo, OpenSUSE
- Alpine, NixOS, Void
- FreeBSD, NetBSD, OpenBSD
- Haiku

### 5.2 LacksDevPackages定数

| 定数 | 内容 |
|------|------|
| LacksDevPackages | 開発パッケージが不要なディストリビューション |

含まれるディストリビューション: Gentoo, Slackware, ArchLinux, Artix, Antergos, BlackArch, ArchBang

### 5.3 foreignDepInstallCmd戻り値

| 項目 | 型 | 説明 |
|------|-----|------|
| (コマンド, sudo必要) | (string, bool) | インストールコマンドとsudo必要性 |

## 6. 処理フロー

### 6.1 detectOs処理フロー

```mermaid
flowchart TD
    A[detectOs呼び出し] --> B{基本OS判定}
    B -->|Windows| C[defined windows]
    B -->|Posix| D[defined posix]
    B -->|MacOSX| E[defined macosx]
    B -->|Linux| F[defined linux]
    B -->|BSD| G[defined bsd]
    B -->|その他| H{プラットフォーム}
    H -->|BSD| I[uname確認]
    H -->|Linux| J{ディストリ判定}
    J -->|Gentoo| K[uname -Gentoo]
    J -->|Ubuntu等| L[/etc/os-release]
    J -->|NixOS| M[NIX環境変数]
    J -->|その他| N[全コマンド実行]
    C --> O[結果返却]
    D --> O
    E --> O
    F --> O
    G --> O
    I --> O
    K --> O
    L --> O
    M --> O
    N --> O
```

### 6.2 foreignDepInstallCmd処理フロー

```mermaid
flowchart TD
    A[foreignDepInstallCmd呼び出し] --> B{プラットフォーム}
    B -->|Windows| C[choco install]
    B -->|BSD| D[ports install]
    B -->|Linux| E{detectOs判定}
    B -->|Haiku| F[pkgman install]
    B -->|その他| G[brew install]
    E -->|Ubuntu/Debian系| H[apt-get install]
    E -->|Fedora| I[yum install]
    E -->|ArchLinux系| J[pacman -S]
    E -->|Gentoo| K[emerge install]
    E -->|NixOS| L[nix-env -i]
    E -->|Void| M[xbps-install]
    E -->|その他| N[プレースホルダ]
    C --> O[コマンド+sudo返却]
    D --> O
    H --> O
    I --> O
    J --> O
    K --> O
    L --> O
    M --> O
    N --> O
    F --> O
    G --> O
```

### 6.3 foreignDep処理フロー

```mermaid
flowchart TD
    A[foreignDep呼び出し] --> B[foreignDepInstallCmd呼び出し]
    B --> C[インストールコマンド取得]
    C --> D[foreignCmd呼び出し]
    D --> E{requiresSudo?}
    E -->|Yes| F[sudo接頭辞追加]
    E -->|No| G[そのまま]
    F --> H[foreignDepsに追加]
    G --> H
```

## 7. ビジネスルール

### 7.1 パッケージマネージャー対応表

| ディストリビューション | パッケージマネージャー | sudo |
|-----------------------|----------------------|------|
| Windows | choco | No |
| Ubuntu, Debian, Elementary, KNOPPIX, SteamOS | apt-get | Yes |
| Fedora | yum | Yes |
| RedHat | rpm | Yes |
| ArchLinux, Manjaro, Artix | pacman | Yes |
| Gentoo | emerge | Yes |
| OpenSUSE | yast | Yes |
| NixOS | nix-env | No |
| Void | xbps-install | Yes |
| Solaris, FreeBSD | pkg | Yes |
| NetBSD, OpenBSD | pkg_add | Yes |
| Haiku | pkgman | Yes |
| macOS（その他） | brew | No |

### 7.2 検出優先順位

1. コンパイル時定義（defined）
2. /etc/os-release
3. lsb_release -d
4. uname -a
5. hostnamectl

### 7.3 キャッシュ動作

| コマンド | キャッシュ変数 |
|---------|---------------|
| uname -a | unameRes |
| cat /etc/os-release | osReleaseIDRes |
| lsb_release -d | releaseRes |
| hostnamectl | hostnamectlRes |

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

該当なし（システム情報取得のみ）

## 9. エラー処理

### 9.1 エラー一覧

| エラー条件 | 発生関数 | 処理 |
|-----------|---------|------|
| コマンド実行失敗 | detectOs | 空文字列として扱われる |
| 不明なディストリビューション | foreignDepInstallCmd | プレースホルダを返す |

### 9.2 フォールバック

| 状況 | 動作 |
|------|------|
| ディストリビューション検出不可 | false返却 |
| パッケージマネージャー不明 | プレースホルダコマンド返却 |

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

該当なし（システム情報取得のみ）

## 11. パフォーマンス要件

| 項目 | 特性 |
|------|------|
| コマンド実行 | 外部プロセス起動のオーバーヘッド |
| キャッシュ | 同一コマンドの再実行を回避 |
| NimScript | gorge()による実行 |

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

### 12.1 コマンド実行

| リスク | 対策 |
|--------|------|
| コマンドインジェクション | 固定コマンドのみ実行 |
| sudo権限要求 | ユーザーへの明示的な表示 |

### 12.2 依存パッケージ

| リスク | 対策 |
|--------|------|
| 不正パッケージ名 | 開発者が正しいパッケージ名を確認 |
| リポジトリ改ざん | OSのパッケージマネージャーに依存 |

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

### 13.1 関連ファイル一覧

| ファイルパス | 概要 | 行数 |
|-------------|------|------|
| lib/pure/distros.nim | ディストリビューション検出モジュール | 280行 |

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

```
distros.nim
├── Distribution enum (36-135行)
├── LacksDevPackages定数 (138-140行)
├── キャッシュ変数 (144行)
├── cmdReleaseテンプレート (146-149行)
│   ├── uname() (151行)
│   ├── osReleaseID() (152行)
│   ├── release() (153行)
│   └── hostnamectl() (154行)
├── detectOsWithAllCmd (156-160行)
├── detectOsImpl (162-205行)
│   ├── 基本OS判定 (164-168行)
│   ├── BSD判定 (170-175行)
│   └── Linux判定 (176-203行)
├── detectOsテンプレート (207-211行)
├── foreignDeps変数 (214行)
├── foreignCmd (216-223行)
├── foreignDepInstallCmd (225-268行)
├── foreignDep (270-274行)
└── echoForeignDeps (276-279行)
```

### 13.3 データフロー図

```
[システムコマンド]
       │
       ├─ uname -a ──────────────────┐
       ├─ cat /etc/os-release ───────┤
       ├─ lsb_release -d ────────────┼──► [キャッシュ変数]
       └─ hostnamectl ───────────────┘
                                          │
                                          ▼
                                   ┌─────────────┐
                                   │ detectOsImpl │
                                   └─────────────┘
                                          │
                                          ▼
                                   [Distribution]
                                          │
                                          ▼
                            ┌──────────────────────────┐
                            │ foreignDepInstallCmd     │
                            └──────────────────────────┘
                                          │
                                          ▼
                                   [コマンド文字列]
                                          │
                                          ▼
                                   ┌──────────────┐
                                   │ foreignCmd   │
                                   └──────────────┘
                                          │
                                          ▼
                                   [foreignDeps]
                                          │
                                          ▼
                               ┌────────────────────┐
                               │ echoForeignDeps    │
                               └────────────────────┘
                                          │
                                          ▼
                                   [標準出力]
```

### 13.4 読み解くべき重要なコード

1. **Distribution enum（36-135行）**: 約100種類のディストリビューション定義
2. **cmdReleaseテンプレート（146-149行）**: コマンド実行とキャッシュ機構
3. **detectOsImpl（162-205行）**: ディストリビューション検出ロジック
4. **foreignDepInstallCmd（225-268行）**: パッケージマネージャー対応表

### 13.5 推奨リーディング順序

1. Distribution enum（36-135行）- 対応ディストリビューション一覧
2. detectOsテンプレート/detectOsImpl（207-211行, 162-205行）- 検出ロジック
3. cmdReleaseテンプレート（146-154行）- コマンド実行とキャッシュ
4. foreignDepInstallCmd（225-268行）- パッケージマネージャー対応
5. foreignDep/foreignCmd（270-274行, 216-223行）- 依存登録
6. 使用例（21-25行）- 実際の使い方

### 13.6 使用例

```nim
if detectOs(Ubuntu):
  foreignDep "libblas-dev"
  foreignDep "libvoodoo"

# 出力:
# sudo apt-get install libblas-dev
# sudo apt-get install libvoodoo
```
