# バッチ設計書 55-init-tools-native.ps1

## 概要

本ドキュメントは、Windows環境でネイティブビルドツール（CMake、Ninja等）を初期化・インストールするためのPowerShellスクリプト `eng/common/init-tools-native.ps1` の設計仕様を記載します。

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

このバッチは、.NET Runtimeのネイティブコード（CoreCLR、ネイティブライブラリ等）のビルドに必要なツールをWindows環境でglobal.jsonの設定に基づいて自動的にインストールするためのスクリプトです。ビルド環境の前提条件を自動的にセットアップし、開発者やCI/CDパイプラインでの環境構築を簡素化します。また、PathPromotion機能により、既にインストール済みのツールを検出してパスに追加することも可能です。

**業務上の目的・背景**：.NET Runtimeはマネージドコードとネイティブコードの両方を含む大規模プロジェクトです。ネイティブコードのビルドには特定バージョンのCMake、Ninja、その他のツールが必要であり、これらのバージョン不一致がビルド失敗の原因となることがあります。このスクリプトにより、global.jsonで定義された正確なバージョンのツールを自動インストールし、ビルド環境の一貫性を保証します。Windows特有の機能として、arcade-toolsディレクトリからの既存ツール検出もサポートしています。

**バッチの実行タイミング**：ネイティブビルドの実行前、またはCI/CDパイプラインの環境セットアップフェーズで実行されます。通常、build.cmdやeng/build.ps1から間接的に呼び出されます。

**主要な処理内容**：
1. コマンドライン引数の解析（BaseUri、InstallDirectory、Clean、Force、PathPromotion等）
2. global.jsonファイルからnative-toolsセクションの読み取り
3. PathPromotion有効時：既存ツールの検出とパス設定
4. PathPromotion無効時：各ツールのインストーラスクリプト（install-tool.ps1）を実行
5. インストール完了後、ツールのパスをPATH環境変数に追加（Azure Pipelines用の出力を含む）

**前後の処理との関連**：このスクリプトは `eng/common/pipeline-logging-functions.ps1` と `eng/common/native/CommonLibrary.psm1` に依存しています。インストールされたツールは、その後のネイティブビルド（CMakeプロジェクトのビルド）で使用されます。

**影響範囲**：ネイティブツールは `%USERPROFILE%\.netcoreeng\native\` または指定されたディレクトリにインストールされます。PATH環境変数が更新され、後続のビルドプロセスからツールが利用可能になります。

## バッチ種別

ツールインストール / 環境セットアップ / ネイティブビルド前処理

## 実行スケジュール

| 項目 | 内容 |
|-----|------|
| 実行頻度 | ビルド実行時（随時） |
| 実行時刻 | ビルド開始時 |
| 実行曜日 | 該当なし |
| 実行日 | 該当なし |
| トリガー | ビルドスクリプト / CI/CDパイプライン / 手動 |

## 実行条件

### 前提条件

| 条件 | 説明 |
|-----|------|
| Windows OS | PowerShell実行環境が必要 |
| global.json | プロジェクトルートに存在し、native-toolsセクションが定義されていること |
| ネットワーク接続 | ツールアーカイブのダウンロードが必要な場合 |

### 実行可否判定

global.jsonにnative-toolsセクションが存在しない場合は、メッセージを出力して正常終了します。

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|-----|-------------|------|
| BaseUri | string | No | https://netcorenativeassets.blob.core.windows.net/resource-packages/external | ツールアーカイブのベースURL |
| InstallDirectory | string | No | %USERPROFILE%\.netcoreeng\native\ | ツールのインストール先ディレクトリ |
| Clean | switch | No | $False | インストールせず、クリーンアップのみ実行 |
| Force | switch | No | $False | クリーンアップ後にインストールを実行 |
| DownloadRetries | int | No | 5 | ダウンロードのリトライ回数 |
| RetryWaitTimeInSeconds | int | No | 30 | リトライ間隔（秒） |
| GlobalJsonFile | string | No | リポジトリルート/global.json | global.jsonのパス |
| PathPromotion | switch | No | $False | 既存ツールのパス追加のみを行う |

### 入力データソース

| データソース | 形式 | 説明 |
|-------------|------|------|
| global.json | JSON | native-toolsセクションにツール名とバージョンを定義 |
| Azure Blob Storage | zip/tar.gz | ツールアーカイブ |
| install-tool.ps1 | PowerShell | 汎用インストーラスクリプト |
| CommonLibrary.psm1 | PowerShellモジュール | 共通関数ライブラリ |

## 出力仕様

### 出力データ

| 出力先 | 形式 | 説明 |
|-------|------|------|
| インストールディレクトリ | ディレクトリ | ツールバイナリ |
| コンソール出力 | テキスト | インストール進捗、結果メッセージ |
| Azure Pipelines出力 | 特殊形式 | ##vso[task.prependpath]によるパス設定 |
| 戻り値 | string/hashtable | インストールパスまたはインストール済みツール情報 |

### 出力ファイル仕様

| 項目 | 内容 |
|-----|------|
| ファイル名 | ツール固有（cmake.exe、ninja.exe等） |
| 出力先 | {InstallDirectory}\bin\ |
| 文字コード | バイナリ |
| 区切り文字 | 該当なし |

## 処理フロー

### 処理シーケンス

```
1. パラメータの受け取りと初期化
   └─ CmdletBinding、StrictMode設定
2. 依存スクリプトの読み込み
   └─ pipeline-logging-functions.ps1、CommonLibrary.psm1
3. global.jsonの読み取り
   └─ ConvertFrom-JsonでJSONパース
4. native-toolsセクションの抽出
   └─ Select-Object -Expand 'native-tools'
5. PathPromotionモードの判定
   └─ arcade-toolsディレクトリの存在確認
6a. PathPromotion有効時：
   └─ 既存ツールの検出とパス追加
6b. PathPromotion無効時：
   └─ install-tool.ps1を呼び出してインストール
7. パス設定
   └─ Azure Pipelines用の##vso出力
8. 終了処理
   └─ 成功: インストールパス返却、失敗: exit 1
```

### フローチャート

```mermaid
flowchart TD
    A[バッチ開始] --> B[パラメータ受け取り]
    B --> C[依存スクリプト読み込み]
    C --> D[global.json読み取り]
    D --> E{native-tools存在?}
    E -->|No| F[メッセージ出力]
    F --> G[exit 0]
    E -->|Yes| H{PathPromotion?}
    H -->|Yes| I{arcade-tools存在?}
    I -->|Yes| J[既存ツール検出]
    J --> K[パスに追加]
    K --> L[InstalledTools返却]
    I -->|No| M[ツール不在エラー出力]
    M --> G
    H -->|No| N[ツールごとにループ]
    N --> O[install-tool.ps1実行]
    O --> P{成功?}
    P -->|No| Q{中断設定?}
    Q -->|Yes| R[エラー exit 1]
    Q -->|No| S[次のツールへ]
    P -->|Yes| S
    S --> T{全ツール完了?}
    T -->|No| N
    T -->|Yes| U{cleanモード?}
    U -->|Yes| G
    U -->|No| V[パス設定出力]
    V --> W[InstallBin返却]
```

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

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 1 | インストールエラー | install-tool.ps1が失敗 | ネットワーク接続確認、-Forceで再実行 |
| 1 | ツール不在エラー | PathPromotion時にツールが見つからない | イメージにツールをインストール |
| 1 | ディレクトリエラー | インストールディレクトリが作成できない | 権限確認、ディスク容量確認 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | $DownloadRetriesで指定（デフォルト5回） |
| リトライ間隔 | $RetryWaitTimeInSecondsで指定（デフォルト30秒） |
| リトライ対象エラー | ダウンロード失敗 |

### 障害時対応

1. ネットワーク接続を確認
2. Azure Blob Storageへのアクセス可能性を確認
3. -Forceオプションで強制再インストールを試行
4. 手動でツールをインストールし、パスを設定
5. global.jsonのnative-toolsセクションを確認
6. -Verboseオプションで詳細ログを確認

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

| 項目 | 内容 |
|-----|------|
| トランザクション範囲 | ツール単位 |
| コミットタイミング | 各ツールのインストール完了時 |
| ロールバック条件 | 失敗したツールは部分的にインストールされる可能性あり（-Cleanで対応） |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定処理件数 | 1-5ツール/実行 |
| 目標処理時間 | 1-10分（ツール数とネットワーク速度に依存） |
| メモリ使用量上限 | アーカイブ展開時に一時的に増加 |

## 排他制御

同一マシン上での同時実行は想定されていません。同じインストールディレクトリへの同時書き込みは競合を引き起こす可能性があります。

## ログ出力

| ログ種別 | 出力タイミング | 出力内容 |
|---------|--------------|---------|
| 開始ログ | 処理開始時 | "Processing $GlobalJsonFile" |
| 進捗ログ | 各ツールインストール時 | インストーラコマンド（Verbose） |
| 完了ログ | 全ツールインストール完了時 | "Native tools are available from {path}" |
| エラーログ | エラー発生時 | Write-PipelineTelemetryErrorによる出力 |

## 監視・アラート

| 監視項目 | 閾値 | アラート先 |
|---------|-----|----------|
| 終了コード | 0以外 | Azure DevOpsパイプライン |
| 処理時間 | 10分超過 | 手動確認 |

## 備考

- このスクリプトはArcade SDKの標準コンポーネントであり、.NET系プロジェクト全体で共有されています
- Linux/macOS版として `eng/common/init-tools-native.sh` が存在します
- PathPromotion機能はビルドマシンイメージにツールがプリインストールされている場合に有用です
- arcade-toolsディレクトリ（C:\arcade-tools）は、ビルドマシンイメージでツールを提供するための標準的な場所です
- 各ツールのbinpath.txtファイルにより、実行可能ファイルの場所が指定されます
- CommonLibrary.psm1モジュールはGet-NativeInstallDirectory等の共通関数を提供します
