# バッチ設計書 47-tools.sh

## 概要

本ドキュメントは、Linux/macOS向けの共通ビルドツール関数を提供するBashスクリプト `eng/common/tools.sh` の設計を記述します。このスクリプトは、.NET SDKの初期化、MSBuild実行、Arcade SDKツールセットの管理など、ビルドプロセスの中核となる機能を提供します。

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

このスクリプトは、他のビルドスクリプトからsourceされて使用される共通関数ライブラリです。直接実行されるのではなく、関数と変数の定義を提供します。

**業務上の目的・背景**：.NET Runtimeプロジェクトは、複雑なビルドプロセスを持つ大規模プロジェクトです。SDKのインストール、バージョン管理、MSBuildの実行、Azure Pipelinesとの連携など、多くのビルドスクリプトで共通して必要な機能があります。本スクリプトはこれらの機能を一元化し、コードの重複を避け、保守性を高めます。

**バッチの実行タイミング**：他のビルドスクリプト（build.sh、msbuild.sh等）からsourceされて使用されます。スクリプト読み込み時に初期化処理が実行されます。

**主要な処理内容**：
1. ビルド変数の初期化（ci、configuration、verbosity等）
2. .NET SDK/CLIの初期化とインストール
3. Arcade SDKツールセットの初期化
4. MSBuild関数の提供（ロギング、エラー処理含む）
5. NuGetキャッシュパスの管理
6. Azure Pipelinesログ関数の提供
7. プロセス管理（終了時のクリーンアップ）

**前後の処理との関連**：ほぼ全てのビルドスクリプトがこのスクリプトをsourceします。build.sh、msbuild.sh、sdk-task.shなどが依存しています。

**影響範囲**：ビルドシステム全体に影響します。このスクリプトの変更は全てのビルドプロセスに波及します。

## バッチ種別

共通ユーティリティ / ライブラリスクリプト

## 実行スケジュール

| 項目 | 内容 |
|-----|------|
| 実行頻度 | 随時（他スクリプトからsource時） |
| 実行時刻 | N/A |
| 実行曜日 | N/A |
| 実行日 | N/A |
| トリガー | 他スクリプトからのsource |

## 実行条件

### 前提条件

| 条件 | 説明 |
|-----|------|
| Bash環境 | Bash 4.0以上推奨 |
| global.json | リポジトリルートにglobal.jsonが存在すること |
| ネットワーク接続 | SDKダウンロード時に必要 |

### 実行可否判定

global.jsonが存在しない場合、SDK初期化が失敗します。

## 入力仕様

### 入力パラメータ

このスクリプトは直接パラメータを受け取らず、環境変数または呼び出し元スクリプトで設定された変数を使用します。

### 環境変数/シェル変数

| 変数名 | デフォルト値 | 説明 |
|-------|-------------|------|
| ci | false | CIモードフラグ |
| source_build | false | ソースビルドモードフラグ |
| pipelines_log | ci時true | Azure Pipelinesログ出力フラグ |
| configuration | Debug | ビルド構成 |
| binary_log | ci時true | バイナリログ出力フラグ |
| verbosity | minimal | MSBuild詳細度 |
| node_reuse | ci時false | MSBuildノード再利用フラグ |
| warn_as_error | true | 警告をエラーとして扱うフラグ |
| use_installed_dotnet_cli | true | システムインストール済みdotnetを使用するフラグ |
| use_global_nuget_cache | ci時false | グローバルNuGetキャッシュを使用するフラグ |
| restore | true | パッケージリストアを実行するフラグ |
| prepare_machine | false | マシン準備/クリーンアップを実行するフラグ |
| from_vmr | false | VMR（Virtual Monolithic Repository）内での実行フラグ |

### 入力データソース

| データソース | 形式 | 説明 |
|-------------|------|------|
| global.json | JSON | SDKバージョン、Arcade SDKバージョン等の定義 |
| dotnet-install.sh | Bash | .NET SDKインストールスクリプト（ダウンロード） |
| configure-toolset.sh | Bash | カスタムツールセット設定（オプション） |

## 出力仕様

### 出力データ

| 出力先 | 形式 | 説明 |
|-------|------|------|
| .dotnet/ | ディレクトリ | インストールされた.NET SDK |
| artifacts/toolset/ | ディレクトリ | Arcade SDKツールセット |
| artifacts/log/ | ディレクトリ | ビルドログ |
| artifacts/tmp/ | ディレクトリ | 一時ファイル |

### 提供される関数

| 関数名 | 説明 |
|-------|------|
| InitializeDotNetCli | .NET CLI/SDKの初期化 |
| InstallDotNetSdk | .NET SDKのインストール |
| InstallDotNet | .NETランタイム/SDKのインストール |
| InitializeBuildTool | ビルドツール（dotnet msbuild）の初期化 |
| InitializeToolset | Arcade SDKツールセットの初期化 |
| GetNuGetPackageCachePath | NuGetパッケージキャッシュパスの取得 |
| MSBuild | MSBuild実行（Arcadeロガー付き） |
| MSBuild-Core | MSBuild実行（コア） |
| GetDarc | DARC CLIの取得 |
| GetSdkTaskProject | SDKタスクプロジェクトパスの取得 |
| ExitWithExitCode | 終了処理 |
| StopProcesses | ビルドプロセスの停止 |

## 処理フロー

### 処理シーケンス

```
1. スクリプト読み込み時の初期化
   └─ 変数のデフォルト値設定
   └─ パス解決（_script_dir、eng_root、repo_root等）
   └─ ディレクトリ作成（toolset_dir、temp_dir、log_dir）
   └─ Azure Pipelines変数の設定
   └─ configure-toolset.shの読み込み（存在する場合）

2. InitializeDotNetCli呼び出し時
   └─ 環境変数の設定（DOTNET_NOLOGO、DOTNET_CLI_TELEMETRY_OPTOUT等）
   └─ システムインストール済みdotnetの検索
   └─ global.jsonからSDKバージョンを読み取り
   └─ 必要に応じてSDKをインストール
   └─ PATHにdotnetを追加

3. InitializeToolset呼び出し時
   └─ NuGetキャッシュパスの設定
   └─ Arcade SDKバージョンの読み取り
   └─ ツールセットの復元（未存在時）
   └─ ツールセットパスの返却

4. MSBuild呼び出し時
   └─ Arcadeロガーの設定
   └─ MSBuild-Coreの呼び出し

5. MSBuild-Core呼び出し時
   └─ CI時の検証（バイナリログ、ノード再利用）
   └─ dotnet msbuildの実行
   └─ エラー処理と終了コード管理
```

### フローチャート

```mermaid
flowchart TD
    A[スクリプトsource] --> B[変数初期化]
    B --> C[パス解決]
    C --> D[ディレクトリ作成]
    D --> E[configure-toolset.sh読み込み]
    E --> F[初期化完了]

    G[InitializeDotNetCli] --> H{SDK存在?}
    H -->|Yes| I[PATHに追加]
    H -->|No| J[dotnet-install.sh実行]
    J --> I

    K[InitializeToolset] --> L{ツールセット存在?}
    L -->|Yes| M[パス返却]
    L -->|No| N[MSBuildでリストア]
    N --> M

    O[MSBuild] --> P[Arcadeロガー設定]
    P --> Q[MSBuild-Core呼び出し]
    Q --> R{成功?}
    R -->|Yes| S[正常終了]
    R -->|No| T[エラー処理]
```

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

本スクリプトはデータベース操作を行いません。

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

| 処理 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| N/A | N/A | N/A | データベース操作なし |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| exit 1 | SDK初期化失敗 | global.jsonにdotnetキーがない | global.jsonを確認 |
| exit 1 | SDKインストール失敗 | ネットワークエラー、ダウンロード失敗 | ネットワークを確認、リトライ |
| exit 2 | ツールセット復元失敗 | Arcade SDKパッケージ取得失敗 | NuGetソースを確認 |
| exit 3 | ツールセットパス不正 | ツールセットファイルが見つからない | 手動でリストアを実行 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | SDKインストール時に最大5回（with_retries関数） |
| リトライ間隔 | 指数バックオフ（3^n - 1秒） |
| リトライ対象エラー | dotnet-install.shの失敗 |

### 障害時対応

1. ネットワーク接続を確認
2. global.jsonの内容を確認
3. NuGetパッケージソースの設定を確認
4. 一時ディレクトリをクリアして再実行

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

| 項目 | 内容 |
|-----|------|
| トランザクション範囲 | N/A（ファイル操作） |
| コミットタイミング | N/A |
| ロールバック条件 | N/A |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定処理件数 | N/A（ライブラリ） |
| 目標処理時間 | SDK初期化: 初回30秒〜数分、2回目以降1秒以内 |
| メモリ使用量上限 | Bash標準使用量内 |

## 排他制御

SDKインストール時、同一ディレクトリへの同時インストールは避けてください。ファイルの競合が発生する可能性があります。

## ログ出力

| ログ種別 | 出力タイミング | 出力内容 |
|---------|--------------|---------|
| 情報ログ | SDK初期化時 | インストール試行メッセージ |
| 情報ログ | MSBuild実行時 | ビルドコマンド情報 |
| エラーログ | 失敗時 | Write-PipelineTelemetryErrorによるCI向けエラー |
| バイナリログ | MSBuild実行時 | artifacts/log/{config}/*.binlog |

## 監視・アラート

| 監視項目 | 閾値 | アラート先 |
|---------|-----|----------|
| SDK初期化時間 | 5分超過 | CI通知 |
| MSBuild失敗 | 1件以上 | CI通知（Write-PipelineSetResult経由） |

## 備考

- dotnet-install.shは30日経過で自動再ダウンロード
- CI環境ではテレメトリ無効化（DOTNET_CLI_TELEMETRY_OPTOUT=1）
- CI環境ではノード再利用無効化（決定論的ビルドのため）
- CI環境ではバイナリログ必須（明示的なオプトアウト除く）
- LTTNG_HOME環境変数をHOMEに設定（CLRログインフラ警告抑制）
- VMR（Virtual Monolithic Repository）内でのビルド時は_InitializeToolset環境変数を優先使用
- SDKのダウンロードは複数のソースを試行（公開、ci.dot.net/public、カスタムフィード）
- Azure Pipelines連携はpipeline-logging-functions.shを通じて実行
