# バッチ設計書 20-excise_stdlib.sh

## 概要

本ドキュメントは、Juliaプロジェクトにおける `contrib/excise_stdlib.sh` のバッチ設計書である。このシェルスクリプトは、標準ライブラリをJuliaメインリポジトリから分離して独立リポジトリに切り出すメンテナンスバッチ処理である。

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

`excise_stdlib.sh` は、`git-filter-repo` ツールを使用して、Juliaメインリポジトリから指定された標準ライブラリのサブディレクトリを抽出し、独立したgitリポジトリとして切り出すバッチ処理である。

**業務上の目的・背景**：Juliaの標準ライブラリの一部は、メインリポジトリ（JuliaLang/julia）から独立したリポジトリとして管理する方向に移行している。独立化により、stdlibごとに個別のCI/CD、バージョン管理、コントリビューションフローを持つことが可能となる。本バッチは、メインリポジトリの `stdlib/{name}/` ディレクトリの完全な履歴を保持したまま、独立リポジトリとして切り出すために使用される。

**バッチの実行タイミング**：新しい標準ライブラリを独立リポジトリに移行する決定がなされた時に手動で実行される。不定期・低頻度の実行であり、プロジェクトのアーキテクチャ変更時にのみ必要となる。

**主要な処理内容**：
1. 一時作業ディレクトリの作成
2. Juliaリポジトリのフルクローン
3. `git filter-repo` による指定stdlib + LICENSE.md のサブディレクトリフィルタリング
4. コミットメッセージ内のIssue/PR参照の書き換え（`#123` -> `JuliaLang/julia#123`）
5. release-/master以外のブランチの削除
6. 結果の確認と手動プッシュ手順の表示

**前後の処理との関連**：本バッチの実行後、結果を確認してから `gh repo create` でGitHub上にリポジトリを作成し、`git push --all` および `git push --tags` で全履歴をプッシュする。その後、README.mdの追加やCI設定が必要。Juliaメインリポジトリ側では、対応するstdlibへの参照を外部パッケージ参照に変更する作業が必要。

**影響範囲**：一時ディレクトリ内に新しいリポジトリが作成される。元のJuliaリポジトリには影響しない（別クローンで操作するため）。

## バッチ種別

メンテナンス / リポジトリ分離

## 実行スケジュール

| 項目 | 内容 |
|-----|------|
| 実行頻度 | 不定期（stdlibの独立化時のみ） |
| 実行時刻 | 指定なし |
| 実行曜日 | 指定なし |
| 実行日 | 指定なし |
| トリガー | 手動（`bash contrib/excise_stdlib.sh {stdlib_name}`） |

## 実行条件

### 前提条件

| 条件 | 説明 |
|-----|------|
| git | gitコマンドが利用可能であること |
| git-filter-repo | `git filter-repo` ツールがインストールされていること（https://github.com/newren/git-filter-repo） |
| ネットワーク接続 | GitHubからのリポジトリクローンに必要 |
| mktemp | 一時ディレクトリ作成コマンドが利用可能であること |
| GitHub CLI（推奨） | `gh` コマンドが利用可能であること（リポジトリ作成に推奨） |

### 実行可否判定

引数（stdlib名）が指定されていない場合、エラーメッセージ `Expected name of stdlib` を表示する（ただし `set -e` ではないため処理は続行される可能性がある）。

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|-----|-------------|------|
| $1（stdlib名） | 文字列 | Yes | なし | 切り出す標準ライブラリの名前（例: `Markdown`） |

### 入力データソース

| データソース | 形式 | 説明 |
|-------------|------|------|
| JuliaLang/juliaリポジトリ | gitリポジトリ | GitHubからクローンされるJuliaメインリポジトリ |

## 出力仕様

### 出力データ

| 出力先 | 形式 | 説明 |
|-------|------|------|
| `$WORKDIR/$STDLIB/` | gitリポジトリ | 切り出された標準ライブラリの独立リポジトリ |

### 出力ファイル仕様

| 項目 | 内容 |
|-----|------|
| ファイル名 | 指定されたstdlib名のディレクトリ |
| 出力先 | `mktemp -d` で作成された一時ディレクトリ内 |
| 文字コード | ソースファイルに依存 |
| 区切り文字 | N/A |

## 処理フロー

### 処理シーケンス

```
1. 引数チェック
   └─ stdlib名が引数として渡されているか確認
2. 一時作業ディレクトリ作成
   └─ mktemp -d でWORKDIRを作成
3. リポジトリクローン
   └─ git clone https://github.com/JuliaLang/julia $STDLIB
4. git filter-repo実行
   └─ --subdirectory-filter stdlib/$STDLIB --path LICENSE.md
   └─ --message-callback でIssue/PR参照を書き換え（#N -> JuliaLang/julia#N）
5. 不要ブランチ削除
   └─ release-*とmaster以外の全ブランチを削除
6. 結果表示
   └─ 作業ディレクトリのパスと後続手順を表示
```

### フローチャート

```mermaid
flowchart TD
    A[excise_stdlib開始] --> B{stdlib名指定?}
    B -->|No| C[エラーメッセージ]
    B -->|Yes| D[一時ディレクトリ作成]
    D --> E[Julia リポジトリクローン]
    E --> F[git filter-repo実行]
    F --> G[Issue/PR参照書き換え]
    G --> H[不要ブランチ削除]
    H --> I[結果と後続手順表示]
    I --> J[excise_stdlib完了]
    C --> J
```

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

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

本バッチはデータベース操作を行わない。gitリポジトリ操作のみである。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| N/A | 引数エラー | stdlib名が未指定 | 引数にstdlib名を指定して再実行 |
| N/A | クローンエラー | GitHubからのクローン失敗 | ネットワーク接続を確認 |
| N/A | filter-repoエラー | git-filter-repoが未インストール | pip install git-filter-repoでインストール |
| N/A | filter-repoエラー | 指定されたstdlibディレクトリが存在しない | stdlib名が正しいか確認 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 自動リトライなし |
| リトライ間隔 | N/A |
| リトライ対象エラー | N/A |

### 障害時対応

1. 一時ディレクトリ（`$WORKDIR`）を削除する
2. エラー原因を修正して再実行する
3. Juliaメインリポジトリには影響しないため、安全に再実行可能

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

| 項目 | 内容 |
|-----|------|
| トランザクション範囲 | N/A（gitリポジトリ操作） |
| コミットタイミング | N/A |
| ロールバック条件 | 一時ディレクトリの削除で完全にロールバック可能 |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定処理件数 | 1つのstdlib |
| 目標処理時間 | 数分〜10分程度（リポジトリサイズとネットワーク速度に依存） |
| メモリ使用量上限 | git filter-repoの使用量に依存（Juliaリポジトリ全体のクローンが必要） |

## 排他制御

特になし。各実行は独立した一時ディレクトリで操作するため、同時実行可能（異なるstdlibに対して）。

## ログ出力

| ログ種別 | 出力タイミング | 出力内容 |
|---------|--------------|---------|
| 進捗ログ | 各ステップ | `Excising stdlib $STDLIB; workdir $WORKDIR`、`Filtering repo`、`Deleting branches` |
| 完了ログ | 処理完了時 | 作業ディレクトリのパスとgh repo create/git pushの手順 |
| リマインダー | 処理完了時 | README.mdの追加とCI設定のリマインダー |

## 監視・アラート

| 監視項目 | 閾値 | アラート先 |
|---------|-----|----------|
| 処理結果 | 異常終了 | 実行者（手動実行のため） |

## 備考

- `set -e` により、いずれかのコマンドが失敗した時点でスクリプトが停止する
- `set -f` によりグロブ展開が無効化されている
- `set -x` によりコマンドのトレース出力が有効化されている
- `git filter-repo` の `--message-callback` により、コミットメッセージ内の `#123` 形式のIssue/PR参照が `JuliaLang/julia#123` 形式に書き換えられる（正規表現: `(\W)(#\d+)` -> `\1JuliaLang/julia\2`）
- `--subdirectory-filter` により、指定されたstdlibのディレクトリがリポジトリルートになる
- `--path LICENSE.md` により、LICENSE.mdも切り出し後のリポジトリに含まれる
- release-*ブランチとmasterブランチのみが保持され、その他のブランチは削除される
- 処理完了後の手動作業: `gh repo create JuliaLang/$STDLIB.jl --push --source=. --public`、`git push --all`、`git push --tags`、README.md追加、CI設定
