# バッチ設計書 14-download_dcd

## 概要

本ドキュメントは、serve-dプロジェクトにおけるテスト用DCDバイナリダウンロードスクリプト `test/data/dcd/download_dcd.d` のバッチ設計書である。DCD（D Completion Daemon）の指定バージョンをGitHubリリースからダウンロードし、テスト環境で利用可能な状態に展開する。

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

本バッチは、serve-dの統合テストで必要となるDCD（D Completion Daemon）バイナリを、GitHubリリースからダウンロードして展開するD言語スクリプトである。

**業務上の目的・背景**：serve-dはD言語のLanguage Server実装であり、DCD（D Completion Daemon）との連携機能を持つ。統合テスト（test/runtests.sh）ではDCDバイナリ（dcd-client、dcd-server）が必要となるが、これらはserve-dのリポジトリには含まれていない。本バッチは、テスト実行前にDCDのプリビルドバイナリをGitHubリリースから自動的に取得することで、テスト環境のセットアップを自動化し、開発者が手動でDCDをビルド・配置する手間を排除する。

**バッチの実行タイミング**：統合テストランナー（test/runtests.sh）から自動的に呼び出される。具体的には、runtests.sh内で `$DC -I../../../workspace-d/source -run download_dcd.d` コマンドにより実行される。DCDバイナリが既にダウンロード済みの場合はダウンロード処理をスキップする。

**主要な処理内容**：
1. workspaced.com.dcd_versionモジュールから最新の既知DCDバージョン番号を取得する
2. 実行プラットフォーム（Windows/Linux/macOS）とアーキテクチャ（x86_64/aarch64）に基づいて、適切なダウンロードURLとアーカイブファイル名を決定する
3. アーカイブファイルが未ダウンロードの場合、GitHubリリースからHTTPSでダウンロードする
4. 既存のdcd-client / dcd-serverバイナリを削除する
5. ダウンロードしたアーカイブ（ZIP/tar.gz）を展開し、dcd-clientとdcd-serverバイナリを配置する

**前後の処理との関連**：本バッチは統合テストランナー test/runtests.sh のDCD依存テスト実行前に呼び出される。ダウンロードされたdcd-client/dcd-serverバイナリは、後続のDCD関連テストケースで使用される。

**影響範囲**：テスト環境にのみ影響する。test/data/dcd/ ディレクトリにDCDバイナリとアーカイブファイルをダウンロード・展開する。本番環境やリリースビルドには影響しない。

## バッチ種別

テストデータ取得 / テスト環境セットアップ

## 実行スケジュール

| 項目 | 内容 |
|-----|------|
| 実行頻度 | 随時（統合テスト実行時） |
| 実行時刻 | 指定なし |
| 実行曜日 | 指定なし |
| 実行日 | 指定なし |
| トリガー | test/runtests.shからの自動呼び出し、またはD言語コンパイラによる手動実行 |

## 実行条件

### 前提条件

| 条件 | 説明 |
|-----|------|
| D言語コンパイラ | rdmdまたはD言語コンパイラ（dmd/ldc2）がPATH上に利用可能であること |
| workspace-dソースへのアクセス | `workspaced.com.dcd_version` モジュールがインポートパスに含まれていること（`-I../../../workspace-d/source` オプションで指定） |
| ネットワーク接続 | GitHubリリースへのHTTPSアクセスが可能であること |
| tar/unzipコマンド | Linux/macOS環境ではtarコマンドが利用可能であること |
| カレントディレクトリ | test/data/dcd/ ディレクトリで実行されること |

### 実行可否判定

- アーカイブファイルが既にカレントディレクトリに存在する場合は、ダウンロード処理をスキップする（ただし展開処理は毎回実行される）
- downloadFile関数内で、出力先ファイルが既に存在する場合はHTTPダウンロードをスキップする

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|-----|-------------|------|
| なし | - | - | - | コマンドライン引数は取らない。DCDバージョンはworkspaced.com.dcd_versionモジュールのlatestKnownDCDVersionから取得する |

### 入力データソース

| データソース | 形式 | 説明 |
|-------------|------|------|
| workspaced.com.dcd_version | D言語モジュール | `latestKnownDCDVersion` 列挙値としてDCDバージョン番号（配列形式: [0, 16, 2]）を定義 |
| GitHub Releases API | HTTPS/バイナリ | `https://github.com/dlang-community/DCD/releases/download/v{ver}/dcd-v{ver}-{platform}.{ext}` 形式のURL |

## 出力仕様

### 出力データ

| 出力先 | 形式 | 説明 |
|-------|------|------|
| dcd-client（.exe） | バイナリ実行ファイル | DCDクライアントバイナリ |
| dcd-server（.exe） | バイナリ実行ファイル | DCDサーバーバイナリ |
| dcd-{ver}.zip / dcd-v{ver}-{platform}.tar.gz | アーカイブ | ダウンロードしたアーカイブファイル（キャッシュとして残る） |

### 出力ファイル仕様

| 項目 | 内容 |
|-----|------|
| ファイル名 | dcd-client, dcd-server（Windowsでは.exe拡張子付き） |
| 出力先 | カレントディレクトリ（test/data/dcd/） |
| 文字コード | バイナリファイル |
| 区切り文字 | なし |

プラットフォーム別のアーカイブファイル名：

| プラットフォーム | アーカイブ名 | ダウンロードURL |
|----------------|------------|---------------|
| Windows (x86_64) | dcd-{ver}.zip | https://github.com/dlang-community/DCD/releases/download/v{ver}/dcd-v{ver}-windows-x86_64.zip |
| Linux (x86_64) | dcd-v{ver}-linux-x86_64.tar.gz | https://github.com/dlang-community/DCD/releases/download/v{ver}/dcd-v{ver}-linux-x86_64.tar.gz |
| macOS (x86_64) | dcd-v{ver}-osx-x86_64.tar.gz | https://github.com/dlang-community/DCD/releases/download/v{ver}/dcd-v{ver}-osx-x86_64.tar.gz |
| macOS (aarch64) | dcd-v{ver}-osx-aarch64.tar.gz | https://github.com/dlang-community/DCD/releases/download/v{ver}/dcd-v{ver}-osx-aarch64.tar.gz |

## 処理フロー

### 処理シーケンス

```
1. DCDバージョン番号の取得
   └─ workspaced.com.dcd_version.latestKnownDCDVersion からバージョン番号を取得（現在: 0.16.2）
2. プラットフォーム固有設定の決定
   └─ Windows/Linux/macOS(x86_64/aarch64) に応じてダウンロードURL、アーカイブ名、展開方法を決定
3. アーカイブのダウンロード判定
   └─ アーカイブファイルが存在しない場合のみダウンロードを実行
4. HTTPSダウンロード
   └─ std.net.curl.download を使用してGitHubリリースからアーカイブをダウンロード
5. 既存バイナリの削除
   └─ dcd-client / dcd-server の既存ファイルを削除（FileExceptionは無視）
6. アーカイブの展開
   └─ Windows: ZipArchiveで展開、Linux/macOS: tar -xzvf で展開
```

### フローチャート

```mermaid
flowchart TD
    A[バッチ開始] --> B[latestKnownDCDVersion からバージョン取得]
    B --> C[プラットフォーム判定]
    C --> D{Windows}
    C --> E{Linux}
    C --> F{macOS}
    D --> G[ZIP形式のURL/ファイル名設定]
    E --> H[tar.gz形式のURL/ファイル名設定 x86_64]
    F --> I{AArch64}
    I -->|Yes| J[tar.gz形式のURL/ファイル名設定 aarch64]
    I -->|No| K[tar.gz形式のURL/ファイル名設定 x86_64]
    G --> L{アーカイブ存在チェック}
    H --> L
    J --> L
    K --> L
    L -->|存在しない| M[GitHubリリースからダウンロード]
    L -->|存在する| N[ダウンロードスキップ]
    M --> O[既存dcd-client/dcd-server削除]
    N --> O
    O --> P[アーカイブ展開]
    P --> Q[バッチ終了]
```

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

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

本バッチはデータベース操作を行わない。

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

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

該当なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| CurlException | ダウンロードエラー | ネットワーク障害、GitHubリリースが存在しない場合 | ネットワーク接続を確認し、指定バージョンのDCDリリースがGitHubに存在するか確認する |
| FileException | ファイル操作エラー | アーカイブファイルの書き込み失敗 | ディスク容量とディレクトリの書き込み権限を確認する |
| ZipException | 展開エラー（Windows） | ZIPファイルが破損している場合 | アーカイブファイルを削除して再ダウンロードする |
| ProcessException | tar実行エラー（Linux/macOS） | tarコマンドが利用不可または失敗した場合 | tarコマンドのインストール状態とアーカイブファイルの整合性を確認する |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 0回（リトライなし） |
| リトライ間隔 | なし |
| リトライ対象エラー | なし（ただしアーカイブファイルのキャッシュ機構により、次回実行時にダウンロードをスキップ可能） |

### 障害時対応

- ダウンロードエラーの場合は、ネットワーク接続を確認し、GitHubリリースURL（`https://github.com/dlang-community/DCD/releases/download/v{ver}/`）にアクセス可能か確認する
- アーカイブ破損の場合は、ダウンロード済みアーカイブファイルを手動で削除してから再実行する
- DCDのバージョンを変更する場合は、`workspace-d/source/workspaced/com/dcd_version.d` の `latestKnownDCDVersion` を更新する

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

| 項目 | 内容 |
|-----|------|
| トランザクション範囲 | なし（データベース操作なし） |
| コミットタイミング | なし |
| ロールバック条件 | なし（展開途中で失敗した場合、部分的なファイルが残る可能性がある） |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定処理件数 | 1件（1つのアーカイブのダウンロードと展開） |
| 目標処理時間 | ネットワーク速度に依存（アーカイブサイズは数MB程度） |
| メモリ使用量上限 | 特になし（ZipArchiveはアーカイブ全体をメモリに読み込むが、数MB程度のため問題にならない） |

## 排他制御

排他制御は不要。統合テストランナーから順次実行される。ただし、同じディレクトリで複数のテストプロセスが同時にダウンロード・展開を行うことは想定されていない。

## ログ出力

| ログ種別 | 出力タイミング | 出力内容 |
|---------|--------------|---------|
| ダウンロード開始ログ | ダウンロード処理開始時 | `Downloading DCD {ver}`（標準出力） |
| ダウンロード詳細ログ | downloadFile実行時 | `Downloading {url} to {path}`（標準エラー出力） |
| 展開ログ（Windows） | ZIPエントリ展開時 | `Unpacking {name}`（標準エラー出力） |

## 監視・アラート

| 監視項目 | 閾値 | アラート先 |
|---------|-----|----------|
| テスト実行結果 | テスト失敗 | CI/CDパイプラインの結果通知（GitHub Actions） |

## 備考

- 本スクリプトはtest/runtests.shから `$DC -I../../../workspace-d/source -run download_dcd.d` として実行される。`-I` オプションにより `workspaced.com.dcd_version` モジュールへのインポートパスが追加される
- DCDバージョンは `workspace-d/source/workspaced/com/dcd_version.d` に `latestKnownDCDVersion = [0, 16, 2]` として定義されている。このバージョンを変更することで、ダウンロード対象のDCDバージョンが変更される
- downloadFile関数にはキャッシュ機構があり、出力先ファイルが既に存在する場合はダウンロードをスキップする。これにより、繰り返しテスト実行時の不要なダウンロードを回避する
- Windows環境ではstd.zip.ZipArchiveによるZIP展開を行い、Linux/macOS環境ではシェルコマンド `tar -xzvf` による展開を行う
- macOS環境ではAArch64（Apple Silicon）とx86_64の両アーキテクチャに対応しており、コンパイル時のversion条件分岐により適切なバイナリが選択される
- 既存のdcd-client/dcd-serverバイナリの削除時にFileExceptionが発生した場合は無視される（ファイルが存在しないケースへの対応）
