# 開発者チュートリアル

このチュートリアルでは、開発環境のセットアップから最初の貢献までを実際に体験します。

## 前提条件

- Git がインストールされている
- Python 3.12+ がインストールされている
- テキストエディタまたは IDE（VS Code推奨）
- GitLab アカウント

## ステップ1: 環境のセットアップ

### 1.1 pipx のインストール

```bash
# macOS/Linux
brew install pipx
pipx ensurepath

# 確認
pipx --version
```

### 1.2 Poetry のインストール

```bash
# pipx を使用
pipx install poetry

# 確認
poetry --version
```

### 1.3 リポジトリのクローン

```bash
# HTTPS でクローン
git clone https://gitlab.com/qumasan/haniwers.git
cd haniwers

# または SSH でクローン（SSH キー設定済みの場合）
git clone git@gitlab.com:qumasan/haniwers.git
cd haniwers
```

### 1.4 依存関係のインストール

```bash
# すべての依存関係をインストール
poetry install --with docs,dev

# インストールを確認
poetry run haniwers --version
```

**期待される出力**:
```
haniwers version: X.X.X
Python version: 3.12.X
Platform: darwin/linux
```

## ステップ2: プロジェクトの探索

### 2.1 プロジェクト構造を理解する

```bash
# ディレクトリ構造を確認
tree -L 2 -I '__pycache__|*.pyc|.venv'

# 主要なディレクトリ
# src/haniwers/v0/   - v0 実装
# src/haniwers/v1/   - v1 実装
# tests/             - テスト
# docs/              - ドキュメント
```

### 2.2 テストを実行する

```bash
# すべてのテストを実行
poetry run pytest

# v1 のみ実行
poetry run pytest tests/v1

# カバレッジ付き
poetry run pytest --cov=haniwers.v1 --cov-report=term
```

**期待される結果**: すべてのテストがパス

### 2.3 ドキュメントをプレビューする

```bash
# ライブプレビューを起動
task livehtml

# または
cd docs
poetry run make livehtml

# ブラウザで http://localhost:8000 を開く
```

## ステップ3: 開発ブランチを作成する

### 3.1 Issue を確認する

[GitLab Issues](https://gitlab.com/qumasan/haniwers/-/issues) から「good first issue」ラベルの付いた Issue を探します。

このチュートリアルでは、架空の Issue を例に進めます：

**Issue #123**: "Add validation for negative threshold values"

### 3.2 ブランチを作成する

```bash
# ブランチを作成
git branch fix-negative-threshold

# ブランチを確認
git branch
```

### 3.3 git worktree で作業スペースを作成

```bash
# プロジェクトルートにいることを確認
pwd
# /path/to/haniwers

# 作業スペースを作成
git worktree add ../worktrees/fix-negative-threshold fix-negative-threshold

# 作業スペースに移動
cd ../worktrees/fix-negative-threshold

# 依存関係をインストール
poetry install
```

## ステップ4: バグを修正する

### 4.1 問題を理解する

架空の問題: `haniwers vth` コマンドが負の閾値を受け入れてしまう。

```bash
# 問題を再現（仮）
poetry run haniwers vth --threshold -100
# エラーが出ずに実行されてしまう
```

### 4.2 関連ファイルを見つける

```bash
# 閾値関連のコードを検索
grep -r "threshold" src/haniwers/v1/ --include="*.py"

# または ripgrep を使用
rg "threshold" src/haniwers/v1/
```

該当ファイル: `src/haniwers/v1/config/model.py` (例)

### 4.3 テストを追加する（TDD）

まずテストを書きます。

**`tests/v1/unit/config/model/test_threshold_validation.py`** を作成:

```python
import pytest
from haniwers.v1.config.model import ThresholdConfig


class TestThresholdValidation:
    """Test threshold value validation."""

    def test_positive_threshold_is_valid(self):
        """Positive threshold values should be accepted."""
        config = ThresholdConfig(value=100)
        assert config.value == 100

    def test_zero_threshold_is_valid(self):
        """Zero threshold value should be accepted."""
        config = ThresholdConfig(value=0)
        assert config.value == 0

    def test_negative_threshold_raises_error(self):
        """Negative threshold values should raise ValidationError."""
        with pytest.raises(ValueError, match="Threshold must be non-negative"):
            ThresholdConfig(value=-100)
```

### 4.4 テストを実行（失敗することを確認）

```bash
poetry run pytest tests/v1/unit/config/model/test_threshold_validation.py -v
```

**期待される結果**: テストが失敗（まだ実装していないため）

### 4.5 実装を追加する

**`src/haniwers/v1/config/model.py`** を編集:

```python
from pydantic import BaseModel, Field, field_validator


class ThresholdConfig(BaseModel):
    """Threshold configuration."""

    value: int = Field(description="Threshold value")

    @field_validator('value')
    @classmethod
    def validate_non_negative(cls, v: int) -> int:
        """Validate that threshold is non-negative."""
        if v < 0:
            raise ValueError('Threshold must be non-negative')
        return v
```

### 4.6 テストを再実行（成功することを確認）

```bash
poetry run pytest tests/v1/unit/config/model/test_threshold_validation.py -v
```

**期待される結果**: すべてのテストがパス ✓

### 4.7 すべてのテストを実行

```bash
# すべてのテストが依然としてパスすることを確認
poetry run pytest
```

## ステップ5: コードを整形する

### 5.1 Ruff でフォーマット

```bash
# コードをフォーマット
poetry run ruff format .

# 静的解析
poetry run ruff check .
```

### 5.2 pre-commit フックを実行

```bash
# pre-commit をインストール（初回のみ）
poetry run pre-commit install

# すべてのチェックを実行
poetry run pre-commit run --all-files
```

すべてのチェックがパスすることを確認します。

## ステップ6: コミットする

### 6.1 変更をステージング

```bash
# 変更を確認
git status

# ファイルをステージング
git add src/haniwers/v1/config/model.py
git add tests/v1/unit/config/model/test_threshold_validation.py
```

### 6.2 Commitizen でコミット

```bash
# 対話的にコミットメッセージを作成
poetry run cz c
```

**対話例**:
```
? Select the type of change you are committing: fix
? What is the scope of this change? (class or file name): config
? Write a short description: prevent negative threshold values
? Provide additional contextual information: (press [enter] to skip)
  Add validation to reject negative threshold values in ThresholdConfig.
  This prevents invalid configurations from being created.
? Is this a BREAKING CHANGE?: No
```

**生成されるコミットメッセージ**:
```
fix(config): prevent negative threshold values

Add validation to reject negative threshold values in ThresholdConfig.
This prevents invalid configurations from being created.
```

### 6.3 コミットを確認

```bash
# コミット履歴を確認
git log -1

# 変更内容を確認
git show HEAD
```

## ステップ7: マージリクエストを作成する

### 7.1 メインブランチの変更を取り込む

```bash
# リモートの最新状態を取得
git fetch origin

# メインブランチの変更を取り込む
git rebase origin/main
```

コンフリクトが発生した場合は、[貢献ガイド](./contributing.md#9-コンフリクトが発生した場合)を参照してください。

### 7.2 リモートにプッシュ

```bash
# リモートにプッシュ
git push --set-upstream origin fix-negative-threshold
```

**ターミナルの出力例**:
```
remote:
remote: To create a merge request for fix-negative-threshold, visit:
remote:   https://gitlab.com/qumasan/haniwers/-/merge_requests/new?merge_request[source_branch]=fix-negative-threshold
remote:
```

### 7.3 MR を作成

#### Option 1: glab CLI を使用

```bash
# MR を作成
glab mr create --target-branch main --template draft
```

#### Option 2: Web UI を使用

1. ターミナルに表示されたリンクをクリック
2. テンプレートから「draft」を選択
3. 以下のように記入:

**Title**:
```
fix(config): prevent negative threshold values
```

**Description** (テンプレートに従う):
```markdown
## Summary
- Add validation to reject negative threshold values
- Implement Pydantic field validator
- Add comprehensive unit tests

## Test plan
- [x] Unit tests added and passing
- [x] All existing tests still pass
- [x] Pre-commit hooks pass
- [x] Code formatted with ruff

## Related Issues
Closes #123
```

4. 「Create merge request」をクリック

### 7.4 レビューを待つ

MR が作成されると、自動的に CI/CD パイプラインが実行されます：

- ✓ Tests
- ✓ Linting
- ✓ Code formatting check
- ✓ Documentation build

レビュアーからのフィードバックを待ちます。

## ステップ8: レビューに対応する（オプション）

レビュアーからコメントがあった場合：

### 8.1 修正する

```bash
# ファイルを編集
vim src/haniwers/v1/config/model.py

# テストを実行
poetry run pytest

# ステージングしてコミット
git add src/haniwers/v1/config/model.py
poetry run cz c
```

### 8.2 プッシュする

```bash
# プッシュ
git push
```

MR が自動的に更新されます。

## ステップ9: マージ後のクリーンアップ

MR がマージされたら：

```bash
# メインブランチに移動
cd ../../haniwers

# メインブランチを更新
git fetch --prune
git pull

# worktree を削除
git worktree remove ../worktrees/fix-negative-threshold

# ブランチを削除
git branch -d fix-negative-threshold
```

## おめでとうございます！ 🎉

最初の貢献が完了しました！

## 次のステップ

1. **他の Issue に取り組む**: [good first issue](https://gitlab.com/qumasan/haniwers/-/issues?label_name%5B%5D=good+first+issue) を探す
2. **ドキュメントを改善する**: ドキュメントの誤りや不足を修正
3. **新機能を提案する**: 新しいアイデアを Issue で提案
4. **レビューに参加する**: 他の人の MR をレビュー

## 参考資料

- [貢献ガイド](./contributing.md): 詳細な貢献手順
- [アーキテクチャ](./architecture.md): プロジェクトの構造
- [テストガイドライン](./testing.md): テスト戦略
- [FAQ](./faq.md): よくある質問

---

**質問がありますか？** [GitLab Issues](https://gitlab.com/qumasan/haniwers/-/issues) で気軽に質問してください！
