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

## 概要

本ドキュメントは、Arcade共通ツール関数スクリプト（tools.sh）の設計仕様を記載したものです。このスクリプトは、.NETプロジェクトのビルドインフラストラクチャであるArcadeフレームワークの中核となる共通関数を提供します。

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

このバッチは、他のビルドスクリプトから読み込まれて使用されるライブラリスクリプトです。.NET SDKのインストール、MSBuild実行、ツールセット初期化、NuGetパッケージキャッシュ管理など、ビルドに必要な基本機能を提供します。

**業務上の目的・背景**：.NETエコシステムでは、多数のリポジトリが共通のビルドインフラストラクチャ（Arcade SDK）を使用しています。tools.shは、Linux/macOS環境でのビルドに必要な共通機能を一元化することで、各リポジトリでのコード重複を排除し、ビルドプロセスの一貫性と保守性を向上させます。

**バッチの実行タイミング**：直接実行されるのではなく、他のスクリプト（build.sh、sdk-task.sh等）から`source`コマンドで読み込まれます。

**主要な処理内容**：
1. 環境変数の初期化（ci、configuration、verbosity等）
2. .NET SDK/CLIの初期化とインストール（InitializeDotNetCli）
3. Arcade SDKツールセットの初期化（InitializeToolset）
4. MSBuildの実行ラッパー（MSBuild、MSBuild-Core）
5. NuGetパッケージキャッシュパスの取得（GetNuGetPackageCachePath）
6. dotnet-install.shスクリプトの取得と実行
7. ビルドプロセスの終了処理（ExitWithExitCode、StopProcesses）

**前後の処理との関連**：pipeline-logging-functions.shを読み込みます。多くのArcadeビルドスクリプトから参照される基盤スクリプトです。

**影響範囲**：環境変数（DOTNET_MULTILEVEL_LOOKUP、PATH等）、ビルドディレクトリ構成、NuGetパッケージキャッシュに影響を与えます。

## バッチ種別

ライブラリスクリプト / 共通関数定義

## 実行スケジュール

| 項目 | 内容 |
|-----|------|
| 実行頻度 | ビルドスクリプト実行時に毎回読み込み |
| 実行時刻 | 他スクリプトからの読み込み時 |
| 実行曜日 | 該当なし |
| 実行日 | 該当なし |
| トリガー | sourceコマンドによる読み込み |

## 実行条件

### 前提条件

| 条件 | 説明 |
|-----|------|
| Bashシェル | /usr/bin/env bashで実行可能 |
| global.json | リポジトリルートにSDKバージョン定義ファイル |
| curl または wget | dotnet-install.shダウンロード用 |
| pipeline-logging-functions.sh | 同一ディレクトリに存在 |

### 実行可否判定

- 読み込み時に即座に初期化処理が実行される
- global.jsonが存在しない場合、SDK初期化でエラー

## 入力仕様

### 入力パラメータ（環境変数）

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|-----|-------------|------|
| ci | boolean | No | false | CI環境での実行かどうか |
| source_build | boolean | No | false | ソースビルドモード |
| configuration | string | No | Debug | ビルド構成 |
| verbosity | string | No | minimal | MSBuild詳細度 |
| restore | boolean | No | true | リストアを実行するか |
| binary_log | boolean | No | CI時true | バイナリログ出力 |
| warn_as_error | boolean | No | true | 警告をエラー扱い |
| use_installed_dotnet_cli | boolean | No | true | 既存の.NET CLIを使用 |
| use_global_nuget_cache | boolean | No | CI時false | グローバルNuGetキャッシュ使用 |

### 入力データソース

| データソース | 形式 | 説明 |
|-------------|------|------|
| global.json | JSON | SDKバージョン、Arcade SDKバージョン定義 |
| dotnet-install.sh | シェルスクリプト | builds.dotnet.microsoft.comから取得 |

## 出力仕様

### 出力データ

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

### 出力ファイル仕様

| 項目 | 内容 |
|-----|------|
| ファイル名 | ToolsetRestore.binlog等 |
| 出力先 | $log_dir |
| 文字コード | バイナリ/テキスト混在 |
| 区切り文字 | 該当なし |

## 処理フロー

### 処理シーケンス

```
[スクリプト読み込み時]
1. 環境変数のデフォルト値設定
   └─ ci, configuration, verbosity等
2. スクリプトパスの解決
   └─ ResolvePath関数でシンボリックリンク解決
3. ディレクトリパスの設定
   └─ repo_root, artifacts_dir, log_dir, temp_dir等
4. global.jsonの解析
   └─ runtimes設定の有無を確認
5. 必要なディレクトリの作成
   └─ toolset_dir, temp_dir, log_dir
6. Azure DevOps変数の設定
   └─ Artifacts, Temp等のパイプライン変数
7. configure-toolset.shの読み込み（存在する場合）

[InitializeDotNetCli呼び出し時]
1. 環境変数の設定
   └─ DOTNET_MULTILEVEL_LOOKUP=0, DOTNET_NOLOGO=1等
2. 既存の.NET CLIの検索
   └─ use_installed_dotnet_cliがtrueの場合
3. global.jsonからSDKバージョン取得
4. SDKのインストール（必要な場合）
   └─ InstallDotNetSdk関数を呼び出し
5. PATHにdotnetを追加

[MSBuild呼び出し時]
1. ビルドツールの初期化
   └─ InitializeBuildTool関数
2. ツールセットの初期化
   └─ InitializeToolset関数
3. Arcade SDKロガーの設定
4. MSBuild-Core関数の呼び出し
```

### フローチャート

```mermaid
flowchart TD
    A[スクリプト読み込み] --> B[環境変数初期化]
    B --> C[パス設定]
    C --> D[ディレクトリ作成]
    D --> E[global.json解析]
    E --> F[Azure DevOps変数設定]
    F --> G[読み込み完了]

    H[InitializeDotNetCli] --> I{既存SDK使用?}
    I -->|Yes| J[既存SDKパス検索]
    I -->|No| K[SDKインストール]
    J --> L[PATH設定]
    K --> L

    M[MSBuild] --> N[InitializeBuildTool]
    N --> O[InitializeToolset]
    O --> P[ロガー設定]
    P --> Q[MSBuild-Core実行]
```

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

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

| 処理 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 該当なし | - | - | このバッチはデータベース操作を行いません |

### テーブル別操作詳細

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 1 | global.json読み取りエラー | キーが見つからない | global.jsonの内容を確認 |
| 1 | SDKインストール失敗 | ダウンロードエラー | ネットワーク接続を確認 |
| 1 | CI環境でバイナリログ無効 | binary_log=falseでCI実行 | -noBinaryLogを明示的に指定 |
| 1 | CI環境でノード再利用有効 | node_reuse=trueでCI実行 | 設定を確認 |
| 2 | ツールセット未リストア | restore=falseでツールセット未取得 | restoreを有効化 |
| 3 | 無効なツールセットパス | ツールセットが見つからない | Arcade SDKリストアを実行 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 5回（with_retries関数） |
| リトライ間隔 | 指数バックオフ（3^n - 1秒） |
| リトライ対象エラー | ネットワーク関連のダウンロードエラー |

### 障害時対応

1. エラーメッセージを確認（Write-PipelineTelemetryErrorの出力）
2. global.jsonの内容を確認
3. ネットワーク接続を確認
4. .dotnetディレクトリを削除して再実行
5. artifacts/toolsetディレクトリを削除して再実行

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

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

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定処理件数 | ビルドごとに1回の初期化 |
| 目標処理時間 | 初回数分、キャッシュ時数秒 |
| メモリ使用量上限 | MSBuild依存 |

## 排他制御

- CI環境ではnode_reuse=falseが強制され、MSBuildノードの再利用が無効化されます
- prepare_machine=trueの場合、終了時にdotnetとvbcscompilerプロセスをkillします

## ログ出力

| ログ種別 | 出力タイミング | 出力内容 |
|---------|--------------|---------|
| 情報ログ | SDKインストール時 | ダウンロードURL、インストール先 |
| 情報ログ | ツールセットリストア時 | リストア結果 |
| エラーログ | 失敗時 | Write-PipelineTelemetryError形式 |
| バイナリログ | MSBuild実行時 | $log_dir/*.binlog |

## 監視・アラート

| 監視項目 | 閾値 | アラート先 |
|---------|-----|----------|
| 終了コード | 0以外 | CI/CDパイプラインの失敗通知 |
| MSBuild実行時間 | タイムアウト設定に依存 | パイプラインのタイムアウト |

## 備考

- 主要な関数一覧：
  - `InitializeDotNetCli`: .NET SDKの初期化とインストール
  - `InitializeToolset`: Arcade SDKツールセットの初期化
  - `InitializeBuildTool`: ビルドツール（dotnet msbuild）の初期化
  - `MSBuild`: MSBuildの実行（ロガー設定含む）
  - `MSBuild-Core`: MSBuildの基本実行
  - `GetNuGetPackageCachePath`: NuGetキャッシュパスの取得
  - `GetDotNetInstallScript`: dotnet-install.shの取得
  - `ExitWithExitCode`: 終了処理
  - `StopProcesses`: ビルドプロセスの強制終了
  - `GetDarc`: DARCツールの取得
  - `GetSdkTaskProject`: SDKタスクプロジェクトパスの取得
- dotnet-install.shは30日ごとに再ダウンロードされます（タイムスタンプファイルで管理）
- CI環境でVMRビルド内の場合、終了コード上書きをスキップします（from_vmr=true）
