# バッチ設計書 15-make_dist_html.py

## 概要

本ドキュメントは、libuvプロジェクトのリリース配布ページHTML生成スクリプト（`tools/make_dist_html.py`）のバッチ設計書である。gitタグからバージョン一覧を抽出し、dist.libuv.org向けのHTMLテーブル（tarball・GPG署名・Windowsインストーラーのダウンロードリンク）を生成する。

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

make_dist_html.pyは、gitリポジトリのタグ情報からlibuvの全リリースバージョンを取得し、メジャー・マイナーバージョンごとにグループ化したHTMLページを標準出力に生成するPythonスクリプトである。

**業務上の目的・背景**：libuvの各バージョンのリリースアーティファクト（tarball、GPG署名、Windowsバイナリ）はdist.libuv.orgで配布されている。バージョンが増えるたびにダウンロードページを手動で更新するのは非効率であるため、gitタグから自動的にHTMLページを生成することで、リリース作業の自動化と人的ミスの防止を実現する。

**バッチの実行タイミング**：新しいリリースバージョンのタグが作成された後に手動で実行する。リリースプロセスの一環として使用される。

**主要な処理内容**：
1. `git tag` コマンドで全タグを取得
2. `v` で始まるタグ（バージョンタグ）をフィルタリング
3. バージョン番号でソート（降順）
4. メジャー・マイナーバージョンでグループ化
5. 各バージョンに対してtarballリンクを生成
6. v1.7.0以降のバージョンにはGPG署名リンクとWindowsバイナリリンクを追加
7. 4列レイアウトのHTMLテーブルとしてフォーマット
8. HTMLを標準出力に出力

**前後の処理との関連**：本スクリプトはリリースプロセスの一部として使用される。前提としてgitタグが正しく設定されている必要がある。出力されたHTMLはdist.libuv.orgにデプロイされる。

**影響範囲**：dist.libuv.orgのダウンロードページの内容に影響する。

## バッチ種別

リリース・パッケージング（HTML生成）

## 実行スケジュール

| 項目 | 内容 |
|-----|------|
| 実行頻度 | リリース時（随時） |
| 実行時刻 | リリースタグ作成後 |
| 実行曜日 | 該当なし |
| 実行日 | 該当なし |
| トリガー | 手動実行 |

## 実行条件

### 前提条件

| 条件 | 説明 |
|-----|------|
| gitコマンド | gitがPATH上に存在しリポジトリ内で実行可能であること |
| gitタグ | vX.Y.Z形式のバージョンタグが設定されていること |
| Python 3 | Python 3実行環境が利用可能であること（shebang: #!/usr/bin/python3） |

### 実行可否判定

スクリプト実行時にgitリポジトリ内にいること、および `git tag` コマンドが実行可能であることが必要。カレントディレクトリはスクリプト配置ディレクトリ（tools/）に自動変更される（`os.chdir(os.path.dirname(__file__))`）。

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|-----|-------------|------|
| 該当なし | - | - | - | コマンドライン引数は受け取らない |

### 入力データソース

| データソース | 形式 | 説明 |
|-------------|------|------|
| git tag | テキスト（改行区切り） | gitリポジトリの全タグ一覧 |

## 出力仕様

### 出力データ

| 出力先 | 形式 | 説明 |
|-------|------|------|
| 標準出力 | HTML | リリース配布ページのHTMLコンテンツ |

### 出力ファイル仕様

| 項目 | 内容 |
|-----|------|
| ファイル名 | 標準出力（リダイレクトでファイル保存可能） |
| 出力先 | stdout |
| 文字コード | UTF-8 |
| 区切り文字 | 該当なし（HTML形式） |

出力HTMLの構造:
- CSSスタイルはlibuv.orgのスタイルシートを参照
- テーブルは4列レイアウト（メジャー・マイナーバージョングループを横に配置）
- 各グループ内にversion/tarball/gpg/windowsの4列テーブル
- dist.libuv.orgへのダウンロードリンクを含む

## 処理フロー

### 処理シーケンス

```
1. カレントディレクトリをスクリプト配置ディレクトリに変更
   └─ os.chdir(os.path.dirname(__file__))
2. git tagコマンド実行
   └─ subprocess.check_output(['git', 'tag'], text=True)
3. バージョンタグのフィルタリング
   └─ 'v'で始まるタグのみ抽出
4. バージョン番号でソート（降順）
   └─ tags.sort(key=version, reverse=True)
5. メジャー・マイナーバージョンでグループ化
   └─ itertools.groupby(tags, major_minor)
6. 各グループのHTML生成
   └─ group_for() で各バージョングループのテーブルHTML生成
7. 各バージョン行のHTML生成
   └─ row_for() でバージョン別のtarball/gpg/exeリンク生成
   └─ v1.7.0以降: GPG署名リンクとWindowsバイナリリンクを追加
8. 4列レイアウトでグループ配置
   └─ groups_for() で4列のHTMLテーブル行を生成
9. 最終HTMLの構築と空白除去
   └─ re.sub('>\\s+<', '><', html) で不要な空白を除去
10. 標準出力に出力
    └─ print(html)
```

### フローチャート

```mermaid
flowchart TD
    A[スクリプト実行] --> B[カレントディレクトリ変更]
    B --> C[git tag実行]
    C --> D[vタグをフィルタリング]
    D --> E[バージョンソート: 降順]
    E --> F[メジャー.マイナーでグループ化]
    F --> G[各グループのHTML生成]
    G --> H{バージョン >= v1.7.0?}
    H -->|Yes| I[tarball + GPG + exeリンク生成]
    H -->|No| J[tarballリンクのみ生成]
    I --> K[4列レイアウト配置]
    J --> K
    K --> L[HTMLテンプレート適用]
    L --> M[空白除去]
    M --> N[標準出力に出力]
```

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

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

本バッチはデータベースを使用しない。

| 処理 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 該当なし | - | - | - |

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

該当なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| CalledProcessError | git実行エラー | gitコマンドが見つからないまたはリポジトリ外で実行 | gitリポジトリ内で実行する |
| AttributeError | パースエラー | タグ名がvX.Y.Z形式に一致しない | 不正なタグを修正または削除する |
| OSError | ディレクトリ変更エラー | スクリプトのディレクトリが取得できない | 正しいパスから実行する |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 0回 |
| リトライ間隔 | 該当なし |
| リトライ対象エラー | 該当なし |

### 障害時対応

1. git tag取得失敗：gitリポジトリ内で実行していることを確認する
2. バージョンパースエラー：不正なタグ名（vX.Y.Z形式でないもの）が存在しないか確認する
3. 出力確認：標準出力をリダイレクトしてHTMLファイルに保存し、ブラウザで表示を確認する

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

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

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定処理件数 | gitタグ数に依存（数十〜数百タグ） |
| 目標処理時間 | 1秒以内 |
| メモリ使用量上限 | 数MB以内 |

## 排他制御

本スクリプトは読み取り専用操作のみ行うため、排他制御は不要。gitタグの追加・削除と同時実行した場合、結果の一貫性は保証されない。

## ログ出力

| ログ種別 | 出力タイミング | 出力内容 |
|---------|--------------|---------|
| 開始ログ | 該当なし | ログ出力なし |
| 進捗ログ | 該当なし | ログ出力なし |
| 終了ログ | 該当なし | ログ出力なし |
| エラーログ | エラー発生時 | Pythonトレースバック |

## 監視・アラート

| 監視項目 | 閾値 | アラート先 |
|---------|-----|----------|
| 該当なし | - | - |

## 備考

- CSSスタイルは `http://libuv.org/styles/vendor.css` と `http://libuv.org/styles/main.css` を外部参照している（HTTP、非HTTPS）
- dist.libuv.orgへのダウンロードリンクもHTTP（非HTTPS）で生成される
- v1.7.0をGPG署名とWindowsバイナリ提供開始の境界バージョンとしてハードコードしている
- HTMLの空白除去（`>\\s+<` を `><` に置換）により、ファイルサイズの圧縮を行っている
- 4列レイアウトは `groups_for()` 関数でパディング処理され、グループ数が4の倍数でない場合も正しく表示される
