# 機能設計書 51-takezip

## 概要

本ドキュメントは、Oh My Zshの`takezip`関数の機能設計を記載する。この関数は、URLからzipファイルをダウンロードして展開し、展開されたディレクトリに自動的に移動するユーティリティ機能である。

### 本機能の処理概要

`takezip`関数は、コマンドライン作業の効率化を目的としたユーティリティ関数であり、zipファイルのダウンロード、展開、ディレクトリ移動を一つのコマンドで実行できる。

**業務上の目的・背景**：開発作業において、GitHubやその他のソースからzipファイルをダウンロードして作業を開始するケースは頻繁にある。通常この作業は、curlでダウンロード、unzipで展開、cdで移動という3ステップが必要だが、`takezip`はこれを1コマンドに集約し、開発者の作業効率を大幅に向上させる。

**機能の利用シーン**：
- GitHubからリリースされたソースコードのzipファイルをダウンロードして作業を開始する場合
- オンラインで配布されているライブラリやツールのzipアーカイブを取得する場合
- 一時的に外部プロジェクトのコードを確認・検証する場合

**主要な処理内容**：
1. 一時ファイルを作成し、curlでURLからzipファイルをダウンロード
2. unzipコマンドでカレントディレクトリに展開
3. 展開されたトップレベルディレクトリ名を取得
4. 一時ファイルを削除
5. 展開されたディレクトリに移動

**関連システム・外部連携**：curl、unzipコマンドに依存。ネットワークアクセスが必要。

**権限による制御**：特にロールによる制御はない。ファイルシステムへの書き込み権限が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | CLIユーティリティのため関連画面なし |

## 機能種別

ファイル操作 / ダウンロード処理 / ディレクトリ操作

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| $1 (URL) | string | Yes | ダウンロードするzipファイルのURL | http/https/ftpで始まる有効なURLであること |

### 入力データソース

コマンドライン引数として直接入力

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 標準出力 | string | unzipコマンドの展開ログ |
| カレントディレクトリ | - | 展開されたディレクトリに変更される |

### 出力先

- ファイルシステム（展開されたファイル群）
- シェルのカレントディレクトリ状態

## 処理フロー

### 処理シーケンス

```
1. 一時ファイル作成
   └─ mktemp コマンドで一時ファイルパスを生成
2. zipファイルダウンロード
   └─ curl -L でURLからデータを取得し一時ファイルに保存
3. zip展開
   └─ unzip でカレントディレクトリに展開
4. トップディレクトリ名取得
   └─ unzip -l と awk/sed でトップレベルディレクトリを抽出
5. 一時ファイル削除
   └─ rm で一時ファイルを削除
6. ディレクトリ移動
   └─ cd で展開ディレクトリに移動
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[一時ファイル作成]
    B --> C[curl でzipダウンロード]
    C --> D[unzip で展開]
    D --> E[トップディレクトリ名取得]
    E --> F[一時ファイル削除]
    F --> G[展開ディレクトリにcd]
    G --> H[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-51-1 | リダイレクト追従 | curl -L オプションによりHTTPリダイレクトを自動追従する | 常時 |
| BR-51-2 | 展開先 | カレントディレクトリに展開される | 常時 |
| BR-51-3 | ディレクトリ名抽出 | zipファイルの4行目のエントリからディレクトリ名を抽出 | 常時 |

### 計算ロジック

展開ディレクトリ名の抽出ロジック：
```
unzip -l "$data" | awk 'NR==4 {print $4}' | sed 's/\/.*//'
```
- `NR==4`：unzip -l の4行目（最初のファイルエントリ）を取得
- `$4`：4番目のフィールド（ファイルパス）を取得
- `sed 's/\/.*//'`：最初のスラッシュ以降を削除してトップディレクトリ名のみ抽出

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

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

本機能はデータベース操作を行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ネットワークエラー | URLへの接続失敗 | curlのエラーメッセージを確認 |
| - | 展開エラー | 不正なzipファイル | unzipのエラーメッセージを確認 |
| - | ディレクトリ移動エラー | 展開ディレクトリが存在しない | zipファイルの構造を確認 |

### リトライ仕様

自動リトライは実装されていない。

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

該当なし（ファイルシステム操作のみ）

## パフォーマンス要件

ネットワーク速度とzipファイルサイズに依存。特定のパフォーマンス要件は定義されていない。

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

- ダウンロードするURLの信頼性はユーザーの責任
- 一時ファイルは処理完了後に削除される
- 展開先はカレントディレクトリのため、意図しない上書きの可能性あり

## 備考

- take関数から呼び出される場合、URLが`.zip`で終わる場合に自動的にこの関数が使用される
- takeurl関数との違いは、tarball形式ではなくzip形式を扱う点

---

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

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

### 推奨読解順序

#### Step 1: 関数定義を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | functions.zsh | `lib/functions.zsh` | takezip関数の定義（63-71行目） |

**読解のコツ**: zshの関数定義では、`function funcname() { ... }` の形式で関数を定義する。ローカル変数は `local` キーワードで宣言する。

#### Step 2: 処理フローを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | functions.zsh | `lib/functions.zsh` | takezip関数の実装（63-71行目） |

**主要処理フロー**:
1. **64行目**: `local data thedir` - ローカル変数の宣言
2. **65行目**: `data="$(mktemp)"` - 一時ファイルの作成
3. **66行目**: `curl -L "$1" > "$data"` - URLからzipファイルをダウンロード
4. **67行目**: `unzip "$data" -d "./"` - カレントディレクトリに展開
5. **68行目**: `thedir="$(unzip -l "$data" | awk 'NR==4 {print $4}' | sed 's/\/.*//')"` - トップディレクトリ名の抽出
6. **69行目**: `rm "$data"` - 一時ファイルの削除
7. **70行目**: `cd "$thedir"` - 展開ディレクトリへの移動

#### Step 3: 呼び出し元を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | functions.zsh | `lib/functions.zsh` | take関数からの呼び出し（78-88行目） |

**主要処理フロー**:
- **81行目**: `elif [[ $1 =~ ^(https?|ftp).*\.(zip)$ ]]; then` - URLがzip拡張子で終わる場合の判定
- **82行目**: `takezip "$1"` - takezip関数の呼び出し

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

```
take()
    │
    └─ takezip()  [URLが.zipで終わる場合]
           │
           ├─ mktemp (外部コマンド)
           ├─ curl -L (外部コマンド)
           ├─ unzip (外部コマンド)
           ├─ awk (外部コマンド)
           ├─ sed (外部コマンド)
           ├─ rm (外部コマンド)
           └─ cd (シェルビルトイン)
```

### データフロー図

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

URL ─────────────▶ curl -L ──────────────▶ 一時ファイル(.zip)
                       │
                       ▼
               一時ファイル(.zip)
                       │
                       ▼
                   unzip -d ./
                       │
                       ▼
               展開されたファイル群
                       │
                       ▼
              トップディレクトリ名取得
                       │
                       ▼
                cd $thedir ─────────────▶ カレントディレクトリ変更
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| functions.zsh | `lib/functions.zsh` | ソース | takezip関数およびtake関数の定義 |
| oh-my-zsh.sh | `oh-my-zsh.sh` | ソース | lib/functions.zshを読み込むエントリポイント |
