# 機能設計書 75-install.sh

## 概要

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

### 本機能の処理概要

`install.sh`は、Oh My Zshを新規インストールするためのシェルスクリプトである。GitHubからOh My Zshリポジトリをクローンし、ユーザーの.zshrcファイルを設定し、オプションでデフォルトシェルをzshに変更する。curl、wget、またはfetchでリモートから直接実行することも、ダウンロードしてローカルで実行することもできる。

**業務上の目的・背景**：Oh My Zshを手動でインストールするには、複数のステップ（gitクローン、.zshrc作成、シェル変更）が必要であり、初心者にとってはハードルが高い。本スクリプトは、ワンライナーでインストールを完了できる手軽さを提供し、Oh My Zshの普及を促進する。

**機能の利用シーン**：
- Oh My Zshを初めてインストールする場合
- 新しいマシンや開発環境のセットアップ時
- Dockerコンテナ等でのプロビジョニング（--unattendedオプション使用）
- CI/CD環境でのテスト用セットアップ

**主要な処理内容**：
1. 環境変数とデフォルト値の設定（$ZSH、$REPO、$REMOTE、$BRANCH等）
2. カラー出力のセットアップ（supports_truecolor、supports_hyperlinks検出）
3. zshのインストール確認
4. setup_ohmyzsh(): GitHubからリポジトリをクローン
5. setup_zshrc(): .zshrcファイルの作成（既存ファイルのバックアップ付き）
6. setup_shell(): chshでデフォルトシェルをzshに変更
7. 成功メッセージの表示とzshの起動

**関連システム・外部連携**：Git（リポジトリクローン）、chsh（シェル変更）、GitHub（リモートリポジトリ）、sudo（権限昇格が必要な場合）。

**権限による制御**：シェル変更（chsh）にはsudo権限が必要な場合がある。umask設定でグループ・その他の書き込み権限を制限。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 17 | install.sh | 主機能 | Oh My Zshをインストールする（リポジトリクローン、.zshrc設定、デフォルトシェル変更） |

## 機能種別

インストール・セットアップ

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| --unattended | flag | No | 非対話モード（RUNZSH=no、CHSH=no） | - |
| --skip-chsh | flag | No | シェル変更をスキップ | - |
| --keep-zshrc | flag | No | 既存の.zshrcを保持 | - |

### 環境変数

| 変数名 | デフォルト | 説明 |
|--------|-----------|------|
| ZSH | $HOME/.oh-my-zsh | OMZインストール先 |
| ZDOTDIR | 未設定 | Zsh dotfilesディレクトリ |
| REPO | ohmyzsh/ohmyzsh | GitHubリポジトリ名 |
| REMOTE | https://github.com/$REPO.git | リモートURL |
| BRANCH | master | チェックアウトするブランチ |
| CHSH | yes | シェル変更を行うか |
| RUNZSH | yes | インストール後にzshを起動するか |
| KEEP_ZSHRC | no | 既存.zshrcを保持するか |
| OVERWRITE_CONFIRMATION | yes | 上書き確認を行うか |

### 入力データソース

- コマンドライン引数
- 環境変数
- 既存の.zshrcファイル（存在する場合）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| OMZリポジトリ | directory | $ZSHにクローンされたOh My Zshリポジトリ |
| .zshrc | file | OMZ設定を含むzsh設定ファイル |
| .zshrc.pre-oh-my-zsh | file | バックアップされた元の.zshrc（存在した場合） |
| .shell.pre-oh-my-zsh | file | 変更前のシェル情報（シェル変更時） |

### 出力先

- $ZSH（デフォルト: ~/.oh-my-zsh）
- $ZDOTDIR または $HOME（.zshrc）

## 処理フロー

### 処理シーケンス

```
1. 環境変数の初期化
   └─ $USER、$HOME、$ZSH等のデフォルト設定
2. 引数解析
   └─ --unattended、--skip-chsh、--keep-zshrc
3. カラー出力セットアップ
   └─ supports_truecolor()、supports_hyperlinks()チェック
4. zshインストール確認
   └─ command_exists zsh
5. $ZSHディレクトリ存在確認
   └─ 既存の場合はエラー終了
6. setup_ohmyzsh()
   └─ git init、git remote add、git fetch、git checkout
7. setup_zshrc()
   └─ 既存.zshrcバックアップ、テンプレートからコピー
8. setup_shell()
   └─ chshでデフォルトシェル変更（オプション）
9. print_success()
   └─ 成功メッセージとソーシャルリンク表示
10. zsh起動
    └─ exec zsh -l（RUNZSH=yes時）
```

### フローチャート

```mermaid
flowchart TD
    A[install.sh開始] --> B[環境変数初期化]
    B --> C[引数解析]
    C --> D{zshインストール済み?}
    D -->|No| E[エラー終了]
    D -->|Yes| F{$ZSH存在?}
    F -->|Yes| G[エラー終了]
    F -->|No| H[setup_ohmyzsh]
    H --> I[setup_zshrc]
    I --> J{CHSH=yes?}
    J -->|Yes| K[setup_shell]
    J -->|No| L[print_success]
    K --> L
    L --> M{RUNZSH=yes?}
    M -->|Yes| N[exec zsh -l]
    M -->|No| O[終了]
    N --> O
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-75-01 | zsh必須 | zshがインストールされていない場合はエラー | 常時 |
| BR-75-02 | 既存$ZSH | $ZSHディレクトリが既に存在する場合はエラー | 常時 |
| BR-75-03 | .zshrcバックアップ | 既存.zshrcは.zshrc.pre-oh-my-zshにバックアップ | 既存.zshrc存在時 |
| BR-75-04 | umask設定 | インストール中はumask g-w,o-wを設定 | setup_ohmyzsh時 |
| BR-75-05 | 非対話モード | stdinがttyでない場合は自動的に非対話モード | stdin非tty時 |

### 計算ロジック

特になし

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

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

データベース操作なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 1 | 依存エラー | zshがインストールされていない | zshをインストールしてから再実行 |
| 1 | 既存ディレクトリ | $ZSHディレクトリが既に存在 | 既存ディレクトリを削除するか、ZSH変数を変更 |
| 1 | gitエラー | gitがインストールされていない、またはクローン失敗 | gitをインストール、ネットワーク確認 |
| 1 | Cygwin gitエラー | CygwinでWindows/MSYS Gitを使用 | Cygwinのgitパッケージをインストール |

### リトライ仕様

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

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

- リポジトリクローン失敗時は$ZSHディレクトリを削除してロールバック
- .zshrc上書き失敗時のバックアップファイル衝突はエラー

## パフォーマンス要件

ネットワーク速度に依存（通常数秒〜数十秒）

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

- HTTPSでGitHubから取得（暗号化通信）
- umaskでファイル権限を制限
- sudo使用時はパスワードプロンプトを強制（-kオプション）
- user_can_sudo()でsudo権限を事前確認

## 備考

- ワンライナーインストール: `sh -c "$(curl -fsSL https://raw.githubusercontent.com/.../install.sh)"`
- Termux環境ではchshの代わりにzsh直接指定を使用
- ZDOTDIR設定時は$ZDOTDIR/ohmyzshにインストール

---

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

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

### 推奨読解順序

#### Step 1: 環境変数とデフォルト設定を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | install.sh | `tools/install.sh` | 環境変数の初期化（44-81行目） |

**読解のコツ**: POSIXシェル互換スクリプト。`${VAR:-default}`はVARが未設定時にdefaultを使用。`${VAR:+value}`はVARが設定時にvalueを使用。

**主要処理フロー**:
- **48行目**: `USER=${USER:-$(id -u -n)}` - ユーザー名のデフォルト設定
- **52-54行目**: `HOME`のデフォルト設定（getent passwd使用）
- **62行目**: `zdot="${ZDOTDIR:-$HOME}"` - dotfilesディレクトリ
- **67-70行目**: `ZSH`のデフォルト設定（ZDOTDIR考慮）
- **73-81行目**: REPO、REMOTE、BRANCH、CHSH、RUNZSH等のデフォルト

#### Step 2: main関数の流れを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | install.sh | `tools/install.sh` | main関数（512-578行目） |

**主要処理フロー**:
- **514-518行目**: stdinがttyでない場合の非対話モード設定
- **521-528行目**: コマンドライン引数の解析
- **530行目**: `setup_color` - カラー出力設定
- **532-535行目**: zshインストール確認
- **537-557行目**: $ZSH存在確認とエラーハンドリング
- **564-566行目**: `setup_ohmyzsh`、`setup_zshrc`、`setup_shell`呼び出し
- **568-575行目**: 成功メッセージとzsh起動

#### Step 3: setup_ohmyzsh関数を理解する

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

**主要処理フロー**:
- **291行目**: `umask g-w,o-w` - セキュアなパーミッション設定
- **295-298行目**: gitインストール確認
- **300-305行目**: Cygwin環境でのMSYS Gitチェック
- **308-318行目**: git init + remote add + fetch + checkout
- **319-325行目**: エラー時のクリーンアップ

#### Step 4: setup_zshrc関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | install.sh | `tools/install.sh` | setup_zshrc関数（332-394行目） |

**主要処理フロー**:
- **340-345行目**: KEEP_ZSHRC=yesの場合のスキップ
- **347-363行目**: 上書き確認ダイアログ
- **365-378行目**: 既存.zshrcのバックアップ
- **384-391行目**: テンプレートから.zshrc生成（$ZSH変数置換）

#### Step 5: setup_shell関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | install.sh | `tools/install.sh` | setup_shell関数（396-490行目） |

**主要処理フロー**:
- **398-405行目**: CHSH=no時、既にzshの場合のスキップ
- **407-414行目**: chshコマンド存在確認
- **418-426行目**: ユーザー確認ダイアログ
- **436-454行目**: /etc/shellsからzshパス取得
- **458-462行目**: 現在のシェルをバックアップ
- **475-479行目**: chsh実行（sudo使用可能時はsudo経由）

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

```
main() (tools/install.sh:512-578)
    │
    ├─ setup_color() (242-283行目)
    │
    ├─ setup_ohmyzsh() (285-330行目)
    │      └─ git init, git remote add, git fetch, git checkout
    │
    ├─ setup_zshrc() (332-394行目)
    │      └─ テンプレート(.zshrc.zsh-template)からコピー
    │
    ├─ setup_shell() (396-490行目)
    │      ├─ user_can_sudo() (88-114行目)
    │      └─ chsh -s $zsh $USER
    │
    ├─ print_success() (493-510行目)
    │
    └─ exec zsh -l
```

### データフロー図

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

環境変数 ──────────────────▶ main()
(ZSH, REPO, BRANCH等)            │
                                 │
コマンドライン引数 ─────────────┤
(--unattended等)                 │
                                 ▼
                           setup_ohmyzsh() ──────────────▶ $ZSH/
                                 │                        (oh-my-zsh repo)
GitHubリポジトリ ────────────────┘
                                 │
                                 ▼
テンプレート ─────────────▶ setup_zshrc() ──────────────▶ ~/.zshrc
(templates/zshrc.zsh-template)   │                        ~/.zshrc.pre-oh-my-zsh
                                 │
既存.zshrc ──────────────────────┘
                                 │
                                 ▼
/etc/shells ──────────────▶ setup_shell() ──────────────▶ シェル変更
                                 │                        ~/.shell.pre-oh-my-zsh
                                 ▼
                           print_success()
                                 │
                                 ▼
                           exec zsh -l
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| install.sh | `tools/install.sh` | ソース | メインインストールスクリプト |
| zshrc.zsh-template | `templates/zshrc.zsh-template` | テンプレート | .zshrcのテンプレート |
| minimal.zshrc | `templates/minimal.zshrc` | テンプレート | 最小限の.zshrc設定例 |
| /etc/shells | システム | 設定 | 有効なシェル一覧 |
