# バッチ設計書 59-common-library.sh

## 概要

本ドキュメントは、ネイティブツールブートストラップで使用される共通ライブラリ関数を提供するBashスクリプト `eng/common/native/common-library.sh` の設計仕様を記載します。

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

このバッチは、ネイティブツールのダウンロード、展開、シム生成などの共通処理を提供するユーティリティライブラリです。他のインストーラスクリプト（install-cmake.sh等）から source コマンドで読み込まれ、再利用可能な関数群を提供します。

**業務上の目的・背景**：ネイティブツール（CMake、Ninja等）のインストール処理には、ダウンロード、アーカイブ展開、パス設定などの共通パターンがあります。これらの処理を各インストーラスクリプトで個別に実装すると、コードの重複と保守の困難さにつながります。このライブラリにより、共通処理を一元化し、インストーラスクリプトの実装を簡素化するとともに、動作の一貫性を保証します。

**バッチの実行タイミング**：直接実行されることは想定されていません。他のスクリプトから source コマンドで読み込まれて使用されます。

**主要な処理内容**：
1. GetNativeInstallDirectory：ネイティブツールのインストールディレクトリを取得
2. GetTempDirectory：一時ディレクトリパスを取得
3. ExpandZip：アーカイブファイルの展開
4. GetCurrentOS：現在のOS名を取得
5. GetFile：ファイルのダウンロードまたはコピー
6. GetTempPathFileName：一時ファイルパスの生成
7. DownloadAndExtract：ダウンロードと展開を一括実行
8. NewScriptShim：実行可能スクリプトのシム生成

**前後の処理との関連**：このスクリプトは他のインストーラスクリプトから source コマンドで読み込まれます。環境変数 NETCOREENG_INSTALL_DIRECTORY を参照してインストール先を決定します。

**影響範囲**：ファイルシステム上にツールをダウンロード・展開します。シムファイルを作成し、パスに追加する準備を行います。

## バッチ種別

ユーティリティライブラリ / 共通関数 / ツールインストール支援

## 実行スケジュール

| 項目 | 内容 |
|-----|------|
| 実行頻度 | ツールインストール時（随時） |
| 実行時刻 | 他スクリプトからの呼び出し時 |
| 実行曜日 | 該当なし |
| 実行日 | 該当なし |
| トリガー | 他スクリプトからのsource呼び出し |

## 実行条件

### 前提条件

| 条件 | 説明 |
|-----|------|
| Linux/macOS OS | Bash実行環境が必要 |
| curl または wget | ダウンロード機能に必要 |
| tar | アーカイブ展開に必要 |

### 実行可否判定

必要なコマンド（curl/wget、tar）が利用可能である必要があります。

## 入力仕様

### 提供関数一覧

| 関数名 | 引数 | 説明 |
|--------|------|------|
| GetNativeInstallDirectory | なし | インストールディレクトリパスを返す |
| GetTempDirectory | なし | 一時ディレクトリパスを返す |
| ExpandZip | zip_path, output_directory, [force] | アーカイブを展開 |
| GetCurrentOS | なし | OS名（Linux/MacOS）を返す |
| GetFile | uri, path, [force], [retries], [wait] | ファイルをダウンロード/コピー |
| GetTempPathFileName | path | 一時ファイルパスを生成 |
| DownloadAndExtract | uri, installDir, [force], [retries], [wait] | ダウンロードして展開 |
| NewScriptShim | shimpath, tool_file_path, [force] | シムスクリプトを生成 |

### 入力データソース

| データソース | 形式 | 説明 |
|-------------|------|------|
| NETCOREENG_INSTALL_DIRECTORY | 環境変数 | カスタムインストールディレクトリ |
| $HOME | 環境変数 | デフォルトインストールディレクトリのベース |

## 出力仕様

### 出力データ

| 出力先 | 形式 | 説明 |
|-------|------|------|
| インストールディレクトリ | ディレクトリ | ツールバイナリ |
| 一時ディレクトリ | ディレクトリ | ダウンロードファイル |
| シムファイル | Bashスクリプト | ツール実行用ラッパー |
| コンソール出力 | テキスト | 進捗、結果メッセージ |

### 関数戻り値

| 関数名 | 戻り値 | 説明 |
|--------|--------|------|
| GetNativeInstallDirectory | パス文字列 | ~/.netcoreeng/native/ または NETCOREENG_INSTALL_DIRECTORY |
| GetTempDirectory | パス文字列 | {インストールディレクトリ}/temp/ |
| GetCurrentOS | OS文字列 | "Linux" または "MacOS" |
| GetTempPathFileName | パス文字列 | 一時ディレクトリ内のファイルパス |
| ExpandZip | 終了コード | 0:成功、1:失敗 |
| GetFile | 終了コード | 0:成功、その他:失敗 |
| DownloadAndExtract | 終了コード | 0:成功、1:失敗 |
| NewScriptShim | 終了コード | 0:成功、1:失敗 |

## 処理フロー

### 各関数の詳細

#### GetNativeInstallDirectory
```
1. NETCOREENG_INSTALL_DIRECTORY 環境変数をチェック
2. 設定されていれば、その値を返す
3. 未設定なら $HOME/.netcoreeng/native/ を返す
```

#### GetTempDirectory
```
1. GetNativeInstallDirectory を呼び出し
2. その結果に "temp/" を付加して返す
```

#### ExpandZip
```
1. 出力ディレクトリの存在確認
2. 既存かつforce=falseならスキップ
3. force=trueなら既存ディレクトリを削除
4. 出力ディレクトリを作成
5. tar -xf でアーカイブを展開
6. 成功/失敗コードを返す
```

#### GetCurrentOS
```
1. uname -s を実行
2. "Linux*" → "Linux"
3. "Darwin*" → "MacOS"
```

#### GetFile
```
1. ファイルが既存かチェック
2. 既存かつforce=falseならスキップ
3. force=trueなら既存ファイルを削除
4. URIがローカルファイルならコピー
5. URIがURLならcurl（優先）またはwgetでダウンロード
6. リトライ設定に従って再試行
```

#### DownloadAndExtract
```
1. GetTempPathFileName で一時ファイルパス取得
2. GetFile でダウンロード
3. ExpandZip で展開
4. 成功/失敗コードを返す
```

#### NewScriptShim
```
1. シムファイルの存在確認
2. 既存かつforce=falseならエラー
3. force=trueなら既存ファイルを削除
4. ツールファイルの存在確認（小文字パスもチェック）
5. シムスクリプト内容を生成
6. ファイルに書き込み
7. chmod +x で実行可能にする
```

### フローチャート（DownloadAndExtract）

```mermaid
flowchart TD
    A[DownloadAndExtract開始] --> B[一時ファイルパス取得]
    B --> C[GetFile呼び出し]
    C --> D{成功?}
    D -->|No| E[エラー出力]
    E --> F[return 1]
    D -->|Yes| G[ExpandZip呼び出し]
    G --> H{成功?}
    H -->|No| I[エラー出力]
    I --> F
    H -->|Yes| J[return 0]
```

```mermaid
flowchart TD
    A[NewScriptShim開始] --> B{シム既存?}
    B -->|Yes| C{force?}
    C -->|No| D[エラー return 1]
    C -->|Yes| E[シム削除]
    B -->|No| F{ツール存在?}
    E --> F
    F -->|No| G[小文字パスチェック]
    G --> H{存在?}
    H -->|No| I[エラー return 1]
    H -->|Yes| J[シム内容生成]
    F -->|Yes| J
    J --> K[ファイル書き込み]
    K --> L[chmod +x]
    L --> M[return 0/1]
```

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

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

本バッチはデータベース操作を行いません。

## エラー処理

### エラーケース一覧

| 関数 | エラー種別 | 発生条件 | 対処方法 |
|------|----------|---------|---------|
| ExpandZip | 展開エラー | tar展開失敗 | アーカイブ形式確認、ディスク容量確認 |
| ExpandZip | 削除エラー | 既存ディレクトリ削除失敗 | 権限確認 |
| GetFile | ダウンロードエラー | curl/wget失敗 | ネットワーク確認、URL確認 |
| GetFile | コピーエラー | ローカルコピー失敗 | パス確認、権限確認 |
| DownloadAndExtract | ダウンロードエラー | GetFile失敗 | 上記参照 |
| DownloadAndExtract | 展開エラー | ExpandZip失敗 | 上記参照 |
| NewScriptShim | 既存ファイルエラー | シム既存かつforce=false | force=trueを指定 |
| NewScriptShim | ツール不在エラー | 指定パスにツールなし | パス確認 |

### リトライ仕様

| 関数 | リトライ回数 | リトライ間隔 |
|------|------------|-------------|
| GetFile | download_retries引数（デフォルト5） | retry_wait_time_seconds引数（デフォルト30秒） |
| DownloadAndExtract | 上記に従う | 上記に従う |

### 障害時対応

1. Write-PipelineTelemetryError でエラー内容を確認
2. ネットワーク接続を確認
3. ディスク容量を確認
4. 権限を確認
5. アーカイブ形式（tar.gz）が正しいか確認

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

| 項目 | 内容 |
|-----|------|
| トランザクション範囲 | 関数単位 |
| コミットタイミング | 各操作完了時 |
| ロールバック条件 | 失敗時は部分的に作成されたファイルが残る可能性あり |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定処理件数 | ツール数に依存 |
| 目標処理時間 | ダウンロードサイズとネットワーク速度に依存 |
| メモリ使用量上限 | tar展開時に一時的に増加 |

## 排他制御

同一ディレクトリへの同時書き込みは競合を引き起こす可能性があります。

## ログ出力

| ログ種別 | 出力タイミング | 出力内容 |
|---------|--------------|---------|
| 進捗ログ | 展開開始時 | "Extracting $zip_path to $output_directory" |
| スキップログ | 既存時 | "Directory already exists, skipping extract" |
| 進捗ログ | ダウンロード時 | "Downloading $uri" |
| スキップログ | ファイル既存時 | "File already exists. Skipping download" |
| エラーログ | 失敗時 | Write-PipelineTelemetryError による出力 |
| 完了ログ | シム生成完了時 | "Finished generating shim" |

## 監視・アラート

| 監視項目 | 閾値 | アラート先 |
|---------|-----|----------|
| 関数戻り値 | 0以外 | 呼び出し元スクリプト |

## 備考

- このスクリプトはArcade SDKの標準コンポーネントであり、.NET系プロジェクト全体で共有されています
- curlが利用可能な場合はcurl、そうでなければwgetを使用します
- シムスクリプトは実際のツールへのラッパーとして機能し、引数をそのまま転送します
- tar コマンドは tar.gz 形式を前提としています
- ツールパスが見つからない場合、小文字に変換して再検索を試みます
- Write-PipelineTelemetryError 関数は pipeline-logging-functions.sh で定義されています
