# 機能設計書 76-setup_ohmyzsh

## 概要

本ドキュメントは、Oh My Zshインストールスクリプト（tools/install.sh）内の`setup_ohmyzsh`関数の機能設計について記述する。

### 本機能の処理概要

`setup_ohmyzsh`関数は、GitHubからOh My Zshリポジトリを$ZSHディレクトリにクローンする処理を担当する。git v1.7.2未満との互換性を確保するため、`git clone`コマンドではなく、`git init` + `git remote add` + `git fetch` + `git checkout`の手順でクローンを実行する。また、セキュリティのためumaskを設定し、クローン失敗時のクリーンアップ処理も行う。

**業務上の目的・背景**：Oh My Zshのインストールには、GitHubリポジトリをローカルに取得する必要がある。本関数は、様々なGit環境（古いバージョン、Cygwin、異なるリモートプロトコル）での互換性を確保しつつ、安全にリポジトリを取得する役割を果たす。

**機能の利用シーン**：
- install.shによるOh My Zshの新規インストール時
- 手動でsetup_ohmyzsh関数を呼び出してリポジトリを取得する場合（稀）

**主要な処理内容**：
1. umask設定（グループ・その他の書き込み権限を除去）
2. gitコマンドの存在確認
3. Cygwin環境でのWindows/MSYS Git検出とエラー
4. git init で空のリポジトリを初期化
5. git config でリポジトリ設定（eol、autocrlf、fsck、oh-my-zsh.remote/branch）
6. git remote add でリモートを追加
7. git fetch --depth=1 で浅いクローン
8. git checkout でブランチをチェックアウト
9. エラー時のクリーンアップ（$ZSHディレクトリ削除）

**関連システム・外部連携**：Git（バージョン管理）、GitHub（リモートリポジトリ）。

**権限による制御**：umask g-w,o-wで作成されるファイルのパーミッションを制限。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 17 | install.sh | 主画面 | Oh My Zshインストールの一部としてリポジトリをクローン |

## 機能種別

リポジトリクローン・セットアップ

## 入力仕様

### 入力パラメータ

setup_ohmyzsh関数自体は引数を取らないが、以下のグローバル変数を参照する。

| 変数名 | 型 | 必須 | 説明 |
|--------|-----|-----|------|
| $ZSH | string | Yes | インストール先ディレクトリパス |
| $REMOTE | string | Yes | リモートリポジトリURL |
| $BRANCH | string | Yes | チェックアウトするブランチ名 |
| $FMT_BLUE | string | No | カラー出力用エスケープシーケンス |
| $FMT_RESET | string | No | カラーリセット用エスケープシーケンス |

### 入力データソース

- グローバル変数（install.shで設定）
- GitHubリモートリポジトリ

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| $ZSHディレクトリ | directory | クローンされたOh My Zshリポジトリ |
| git設定 | config | oh-my-zsh.remote、oh-my-zsh.branch等の設定 |

### 出力先

- $ZSH（デフォルト: ~/.oh-my-zsh）

## 処理フロー

### 処理シーケンス

```
1. umask設定
   └─ umask g-w,o-w（グループ・その他の書き込み権限除去）
2. 開始メッセージ表示
   └─ "Cloning Oh My Zsh..."
3. gitコマンド存在確認
   └─ command_exists git、なければエラー終了
4. Cygwin環境チェック
   └─ Windows/MSYS Gitの場合はエラー
5. git initでリポジトリ初期化
   └─ git init --quiet "$ZSH"
6. git config設定
   └─ core.eol lf
   └─ core.autocrlf false
   └─ fsck.zeroPaddedFilemode ignore
   └─ fetch.fsck.zeroPaddedFilemode ignore
   └─ receive.fsck.zeroPaddedFilemode ignore
   └─ oh-my-zsh.remote origin
   └─ oh-my-zsh.branch $BRANCH
7. リモート追加とfetch
   └─ git remote add origin "$REMOTE"
   └─ git fetch --depth=1 origin
8. ブランチチェックアウト
   └─ git checkout -b "$BRANCH" "origin/$BRANCH"
9. 元のディレクトリに戻る
   └─ cd -
10. エラー時クリーンアップ
    └─ $ZSHディレクトリを削除
```

### フローチャート

```mermaid
flowchart TD
    A[setup_ohmyzsh開始] --> B[umask g-w,o-w設定]
    B --> C{git存在?}
    C -->|No| D[エラー: git not installed]
    D --> E[exit 1]
    C -->|Yes| F{Cygwin?}
    F -->|Yes| G{MSYS Git?}
    G -->|Yes| H[エラー: MSYS Git not supported]
    H --> E
    G -->|No| I[git init]
    F -->|No| I
    I --> J[git config設定]
    J --> K[git remote add origin]
    K --> L["git fetch --depth=1"]
    L --> M{fetch成功?}
    M -->|No| N[rm -rf $ZSH]
    N --> O[エラー: clone failed]
    O --> E
    M -->|Yes| P[git checkout -b]
    P --> Q{checkout成功?}
    Q -->|No| N
    Q -->|Yes| R[cd -]
    R --> S[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-76-01 | umaskセキュリティ | グループ・その他の書き込み権限を除去 | 常時 |
| BR-76-02 | 浅いクローン | --depth=1で最新コミットのみ取得 | 常時 |
| BR-76-03 | Cygwin互換性 | CygwinではMSYS Gitは非サポート | Cygwin環境時 |
| BR-76-04 | 古いGit互換 | git init + fetch方式でv1.7.2未満に対応 | 常時 |
| BR-76-05 | エラー時クリーンアップ | 失敗時は$ZSHディレクトリを削除 | クローン失敗時 |

### 計算ロジック

特になし

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

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

データベース操作なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 1 | 依存エラー | gitがインストールされていない | gitをインストールしてから再実行 |
| 1 | 環境エラー | CygwinでWindows/MSYS Gitを使用 | Cygwinのgitパッケージを使用 |
| 1 | クローンエラー | git操作に失敗 | ネットワーク確認、リポジトリURL確認 |

### リトライ仕様

リトライは不要（手動で再実行）

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

- 失敗時は$ZSHディレクトリを削除してクリーンアップ
- 中間状態を残さない

## パフォーマンス要件

ネットワーク速度に依存（通常数秒〜十数秒、--depth=1により最小限のデータ転送）

## セキュリティ考慮事項

- umaskでファイル権限を制限（compinit()のセキュリティ警告を回避）
- HTTPSでGitHubから取得（暗号化通信）
- fsckエラーを無視する設定は既知の互換性問題（#4069、#4963）への対応

## 備考

- 古いGit（v1.7.2未満）では一部のgit cloneオプションがサポートされていないため、手動でのinit + fetch + checkout方式を採用
- oh-my-zsh.remoteとoh-my-zsh.branchはupgrade.shで参照される
- zeroPaddedFilemodeエラーは特定のファイルモードに関するfsckチェックを無視

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: 関数の全体構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | install.sh | `tools/install.sh` | setup_ohmyzsh関数の定義（285-330行目） |

**読解のコツ**: POSIXシェル互換スクリプト。`command_exists`は84-86行目で定義されたヘルパー関数。`fmt_error`は238-240行目で定義。

**主要処理フロー**:
- **291行目**: `umask g-w,o-w` - パーミッションセキュリティ設定
- **293行目**: "Cloning Oh My Zsh..." メッセージ出力
- **295-298行目**: gitコマンド存在確認
- **300-305行目**: Cygwin + MSYS Gitチェック
- **308-318行目**: git init + config + remote + fetch + checkout
- **319-325行目**: エラー時クリーンアップ
- **327行目**: `cd -` で元のディレクトリに戻る

#### Step 2: git設定の詳細を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | install.sh | `tools/install.sh` | git config設定（308-315行目） |

**主要処理フロー**:
- **309行目**: `git config core.eol lf` - 改行コードをLFに統一
- **310行目**: `git config core.autocrlf false` - 自動改行変換を無効化
- **311-313行目**: `fsck.zeroPaddedFilemode ignore` - fsckエラー回避
- **314行目**: `oh-my-zsh.remote origin` - OMZ用リモート設定
- **315行目**: `oh-my-zsh.branch "$BRANCH"` - OMZ用ブランチ設定

#### Step 3: ヘルパー関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | install.sh | `tools/install.sh` | command_exists関数（84-86行目） |
| 3-2 | install.sh | `tools/install.sh` | fmt_error関数（238-240行目） |

**主要処理フロー**:
- **command_exists**: `command -v "$@" >/dev/null 2>&1` - コマンド存在確認
- **fmt_error**: 赤色ボールドでエラーメッセージを標準エラー出力

### プログラム呼び出し階層図

```
setup_ohmyzsh() (tools/install.sh:285-330)
    │
    ├─ umask g-w,o-w
    │
    ├─ command_exists git
    │
    ├─ uname (Cygwin検出用)
    │
    ├─ git --version (MSYS Git検出用)
    │
    ├─ git init --quiet "$ZSH"
    │
    ├─ git config (複数回)
    │      ├─ core.eol lf
    │      ├─ core.autocrlf false
    │      ├─ fsck.zeroPaddedFilemode ignore
    │      ├─ fetch.fsck.zeroPaddedFilemode ignore
    │      ├─ receive.fsck.zeroPaddedFilemode ignore
    │      ├─ oh-my-zsh.remote origin
    │      └─ oh-my-zsh.branch $BRANCH
    │
    ├─ git remote add origin "$REMOTE"
    │
    ├─ git fetch --depth=1 origin
    │
    ├─ git checkout -b "$BRANCH" "origin/$BRANCH"
    │
    └─ cd -
```

### データフロー図

```
[入力]                          [処理]                           [出力]

$ZSH ─────────────────────▶ setup_ohmyzsh()
(インストール先パス)              │
                                 │
$REMOTE ─────────────────────────┤
(リモートURL)                    │
                                 │
$BRANCH ─────────────────────────┤
(ブランチ名)                     │
                                 ▼
                           git init
                                 │
                                 ▼
                           git config ───────────▶ .git/config
                                 │
                                 ▼
GitHubリポジトリ ────────▶ git fetch ─────────────▶ $ZSH/.git/objects
                                 │
                                 ▼
                           git checkout ──────────▶ $ZSH/
                                                    (ワーキングツリー)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| install.sh | `tools/install.sh` | ソース | setup_ohmyzsh関数の定義元 |
| upgrade.sh | `tools/upgrade.sh` | ソース | oh-my-zsh.remote/branchを参照 |
| .git/config | `$ZSH/.git/config` | 設定 | リポジトリ設定ファイル |
