# バッチ設計書 7-require_tool.sh

## 概要

本ドキュメントは、指定したツールが必要なバージョン以上かを確認するユーティリティシェルスクリプト`require_tool.sh`のバッチ設計書である。

### 本バッチの処理概要

このバッチは指定されたプログラムのバージョンを検出し、要求される最小バージョンと比較して、条件を満たしているかを判定する。ビルドスクリプトやセットアップスクリプトからの呼び出しを想定したユーティリティである。

**業務上の目的・背景**：ソフトウェアの依存関係管理において、特定のツールやコンパイラが必要なバージョン以上であることを確認することは重要である。このスクリプトは、バージョン比較ロジックを提供し、ビルド前の前提条件チェックやCI/CDパイプラインでの依存関係検証を支援する。

**バッチの実行タイミング**：他のスクリプトからの呼び出し、またはコマンドラインからの手動実行（随時）。

**主要な処理内容**：
1. コマンドライン引数の解析（ツール名、最小バージョン）
2. 環境変数からのツールパス解決（大文字環境変数の確認）
3. `--version`オプションでバージョン文字列を取得
4. バージョン文字列からバージョン番号を抽出（正規表現）
5. strverscmp互換のバージョン比較（AWKを使用）
6. 比較結果に基づく終了コードの返却

**前後の処理との関連**：このスクリプトは汎用ユーティリティとして設計されており、他のスクリプトやMakefile、CI設定から呼び出される。Oh My Zsh固有の依存関係はない。

**影響範囲**：標準出力/標準エラー出力へのメッセージ出力のみ（ファイル変更なし）

## バッチ種別

ユーティリティ / バージョン検証

## 実行スケジュール

| 項目 | 内容 |
|-----|------|
| 実行頻度 | 随時（他スクリプトからの呼び出し） |
| 実行時刻 | 任意 |
| 実行曜日 | 該当なし |
| 実行日 | 該当なし |
| トリガー | 手動実行または他スクリプトからの呼び出し |

## 実行条件

### 前提条件

| 条件 | 説明 |
|-----|------|
| AWKインストール済み | バージョン比較にAWKを使用 |
| 対象ツールインストール済み | 検証対象のツールが利用可能であること |

### 実行可否判定

1. 引数が2つ以外の場合はエラー
2. 対象ツールが見つからない場合はエラー
3. バージョン取得に失敗した場合はエラー

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|-----|-------------|------|
| TOOL | 文字列 | Yes | - | ツール名またはパス |
| MIN_VERSION | 文字列 | Yes | - | 最小必要バージョン |
| -h, --help | フラグ | No | - | ヘルプメッセージを表示 |

### 環境変数

| 環境変数名 | 必須 | デフォルト値 | 説明 |
|-----------|-----|-------------|------|
| ${TOOL_UPPER} | No | - | ツール名を大文字にした環境変数（例: CC=gcc） |

### 入力データソース

| データソース | 形式 | 説明 |
|-------------|------|------|
| $tool --version | 標準出力 | ツールのバージョン情報 |

## 出力仕様

### 出力データ

| 出力先 | 形式 | 説明 |
|-------|------|------|
| 標準エラー出力 | テキスト | エラーメッセージ |
| 終了コード | 数値 | 0: 成功、1: 失敗 |

### 終了コード

| コード | 意味 |
|--------|------|
| 0 | ツールが必要バージョン以上 |
| 1 | ツールが見つからない、バージョン取得失敗、またはバージョン不足 |

## 処理フロー

### 処理シーケンス

```
1. 引数解析
   ├─ -h/--help: usage表示 → 終了（0）
   └─ 引数が2つ以外: エラーメッセージ → 終了（1）

2. ツールパス解決
   ├─ 環境変数チェック（ツール名を大文字化）
   │   └─ 例: CC環境変数が定義されていればそれを使用
   └─ 定義されていなければツール名をそのまま使用

3. バージョン取得
   ├─ $tool --version を実行
   ├─ sedでバージョン番号を抽出（[0-9]*\.[0-9.]*）
   └─ バージョン取得失敗: "$tool is required" → 終了（1）

4. バージョン比較（__require_tool_version_compare）
   ├─ AWKによるstrverscmp互換比較
   ├─ 数字とテキストの混合バージョンに対応
   └─ 結果: '<', '=', '>'

5. 結果判定
   ├─ '>' の場合: バージョン不足エラー → 終了（1）
   └─ それ以外: 成功 → 終了（0）
```

### フローチャート

```mermaid
flowchart TD
    A[バッチ開始] --> B{-h/--help?}
    B -->|Yes| C[usage表示]
    C --> D[終了 0]
    B -->|No| E{引数 = 2?}
    E -->|No| F[エラーメッセージ]
    F --> G[終了 1]
    E -->|Yes| H[ツールパス解決]
    H --> I[環境変数チェック]
    I --> J[$tool --version実行]
    J --> K{バージョン取得成功?}
    K -->|No| L["$tool is required"]
    L --> G
    K -->|Yes| M[バージョン比較]
    M --> N{比較結果}
    N -->|>| O["$tool $version or better is required"]
    O --> G
    N -->|<= | P[終了 0]
```

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

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

該当なし（本スクリプトはデータベース操作を行わない）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 1 | 引数エラー | 引数が2つでない | 正しい引数で再実行 |
| 1 | ツール未検出 | ツールが見つからないまたは--version失敗 | ツールをインストール |
| 1 | バージョン不足 | ツールバージョンが最小要件未満 | ツールを更新 |

### リトライ仕様

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

### 障害時対応

該当なし（判定ツール）

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

| 項目 | 内容 |
|-----|------|
| トランザクション範囲 | 該当なし |
| コミットタイミング | 該当なし |
| ロールバック条件 | 該当なし |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定処理件数 | 1回の実行で1ツール |
| 目標処理時間 | 1秒未満 |
| メモリ使用量上限 | 通常のシェルスクリプト実行範囲 |

## 排他制御

該当なし（読み取り専用操作）

## ログ出力

| ログ種別 | 出力タイミング | 出力内容 |
|---------|--------------|---------|
| エラー出力 | ツール未検出時 | "$tool is required" |
| エラー出力 | バージョン不足時 | "$1 $2 or better is required: this is $tool $version" |

## 監視・アラート

| 監視項目 | 閾値 | アラート先 |
|---------|-----|----------|
| 該当なし | - | - |

## 備考

### バージョン比較アルゴリズム

`__require_tool_version_compare`関数はGNU Cライブラリの`strverscmp`関数と互換性のあるバージョン比較を実装している。

**特徴：**
- 数字部分は数値として比較
- 先頭ゼロは小数として扱う（例: 0.1 < 0.9）
- 文字部分は辞書順で比較
- 7th edition Unix AWK（1978）との互換性を維持

**比較例：**
```
1.0 < 1.1
1.9 < 1.10
0.1 < 0.9
2.0 > 1.99
```

### 環境変数によるツール指定

ツール名を大文字に変換した環境変数が定義されている場合、その値をツールパスとして使用する。

**例：**
```bash
$ CC=g++ require_tool.sh cc 4.6
# → g++ のバージョンをチェック

$ require_tool.sh gcc 4.6
# → gcc のバージョンをチェック（環境変数GCCが未定義の場合）
```

### バージョン抽出パターン

`sed -n 's/.*[^0-9.]\([0-9]*\.[0-9.]*\).*/\1/p;q'`

- 最初の行からバージョン番号を抽出
- `X.Y` または `X.Y.Z` 形式に対応
- 数字とピリオド以外の文字の後に続くバージョン番号を検出

### 使用例

```bash
$ require_tool.sh emacs 23
$ CC=g++ require_tool.sh cc 4.6
$ require_tool.sh zsh 4.5
```
