soba-cli 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.claude/commands/osoba/add-backlog.md +173 -0
- data/.claude/commands/osoba/implement.md +151 -0
- data/.claude/commands/osoba/plan.md +217 -0
- data/.claude/commands/osoba/review.md +133 -0
- data/.claude/commands/osoba/revise.md +176 -0
- data/.claude/commands/soba/implement.md +88 -0
- data/.claude/commands/soba/plan.md +93 -0
- data/.claude/commands/soba/review.md +91 -0
- data/.claude/commands/soba/revise.md +76 -0
- data/.devcontainer/.env +2 -0
- data/.devcontainer/Dockerfile +3 -0
- data/.devcontainer/LICENSE +21 -0
- data/.devcontainer/README.md +85 -0
- data/.devcontainer/bin/devcontainer-common.sh +50 -0
- data/.devcontainer/bin/down +35 -0
- data/.devcontainer/bin/rebuild +10 -0
- data/.devcontainer/bin/up +11 -0
- data/.devcontainer/compose.yaml +28 -0
- data/.devcontainer/devcontainer.json +53 -0
- data/.devcontainer/post-attach.sh +29 -0
- data/.devcontainer/post-create.sh +62 -0
- data/.devcontainer/setup/01-os-package.sh +19 -0
- data/.devcontainer/setup/02-npm-package.sh +22 -0
- data/.devcontainer/setup/03-mcp-server.sh +33 -0
- data/.devcontainer/setup/04-tool.sh +17 -0
- data/.devcontainer/setup/05-soba-setup.sh +66 -0
- data/.devcontainer/setup/scripts/functions/install_apt.sh +77 -0
- data/.devcontainer/setup/scripts/functions/install_npm.sh +71 -0
- data/.devcontainer/setup/scripts/functions/mcp_config.sh +14 -0
- data/.devcontainer/setup/scripts/functions/print_message.sh +59 -0
- data/.devcontainer/setup/scripts/setup/mcp-markdownify.sh +39 -0
- data/.devcontainer/sync-envs.sh +58 -0
- data/.envrc.sample +7 -0
- data/.rspec +4 -0
- data/.rubocop.yml +70 -0
- data/.rubocop_airbnb.yml +2 -0
- data/.rubocop_todo.yml +74 -0
- data/.tool-versions +1 -0
- data/CLAUDE.md +20 -0
- data/LICENSE +21 -0
- data/README.md +384 -0
- data/README_ja.md +384 -0
- data/Rakefile +18 -0
- data/bin/soba +120 -0
- data/config/config.yml.example +36 -0
- data/docs/business/INDEX.md +6 -0
- data/docs/business/overview.md +42 -0
- data/docs/business/workflow.md +143 -0
- data/docs/development/INDEX.md +10 -0
- data/docs/development/architecture.md +69 -0
- data/docs/development/coding-standards.md +152 -0
- data/docs/development/distribution.md +26 -0
- data/docs/development/implementation-guide.md +103 -0
- data/docs/development/testing-strategy.md +128 -0
- data/docs/development/tmux-management.md +253 -0
- data/docs/document_system.md +58 -0
- data/lib/soba/commands/config/show.rb +63 -0
- data/lib/soba/commands/init.rb +778 -0
- data/lib/soba/commands/open.rb +144 -0
- data/lib/soba/commands/start.rb +442 -0
- data/lib/soba/commands/status.rb +175 -0
- data/lib/soba/commands/stop.rb +147 -0
- data/lib/soba/config_loader.rb +32 -0
- data/lib/soba/configuration.rb +268 -0
- data/lib/soba/container.rb +48 -0
- data/lib/soba/domain/issue.rb +38 -0
- data/lib/soba/domain/phase_strategy.rb +74 -0
- data/lib/soba/infrastructure/errors.rb +23 -0
- data/lib/soba/infrastructure/github_client.rb +399 -0
- data/lib/soba/infrastructure/lock_manager.rb +129 -0
- data/lib/soba/infrastructure/tmux_client.rb +331 -0
- data/lib/soba/services/ansi_processor.rb +92 -0
- data/lib/soba/services/auto_merge_service.rb +133 -0
- data/lib/soba/services/closed_issue_window_cleaner.rb +96 -0
- data/lib/soba/services/daemon_service.rb +83 -0
- data/lib/soba/services/git_workspace_manager.rb +102 -0
- data/lib/soba/services/issue_monitor.rb +29 -0
- data/lib/soba/services/issue_processor.rb +215 -0
- data/lib/soba/services/issue_watcher.rb +193 -0
- data/lib/soba/services/pid_manager.rb +87 -0
- data/lib/soba/services/process_info.rb +58 -0
- data/lib/soba/services/queueing_service.rb +98 -0
- data/lib/soba/services/session_logger.rb +111 -0
- data/lib/soba/services/session_resolver.rb +72 -0
- data/lib/soba/services/slack_notifier.rb +121 -0
- data/lib/soba/services/status_manager.rb +74 -0
- data/lib/soba/services/test_process_manager.rb +84 -0
- data/lib/soba/services/tmux_session_manager.rb +251 -0
- data/lib/soba/services/workflow_blocking_checker.rb +73 -0
- data/lib/soba/services/workflow_executor.rb +256 -0
- data/lib/soba/services/workflow_integrity_checker.rb +151 -0
- data/lib/soba/templates/claude_commands/implement.md +88 -0
- data/lib/soba/templates/claude_commands/plan.md +93 -0
- data/lib/soba/templates/claude_commands/review.md +91 -0
- data/lib/soba/templates/claude_commands/revise.md +76 -0
- data/lib/soba/version.rb +5 -0
- data/lib/soba.rb +44 -0
- data/lib/tasks/gem.rake +75 -0
- data/soba-cli.gemspec +59 -0
- metadata +430 -0
@@ -0,0 +1,143 @@
|
|
1
|
+
# soba 自動ワークフロー
|
2
|
+
|
3
|
+
## 概要
|
4
|
+
|
5
|
+
sobaは、GitHub Issueを起点とした自律的な開発ワークフローを実現します。Issue のラベルに基づいて自動的に計画と実装のサイクルを実行します。
|
6
|
+
|
7
|
+
## ワークフローの流れ
|
8
|
+
|
9
|
+
```mermaid
|
10
|
+
graph TD
|
11
|
+
A[複数のsoba:todo] -->|soba: 優先度判定| B[1つをsoba:queued]
|
12
|
+
B -->|soba: 即座に| C[soba:planning]
|
13
|
+
C -->|Claude: 計画策定| D[soba:ready]
|
14
|
+
D -->|soba: 自動検出| E[soba:doing]
|
15
|
+
E -->|Claude: 実装・PR作成| F[soba:review-requested]
|
16
|
+
F -->|soba: 自動検出| G[soba:reviewing]
|
17
|
+
G -->|Claude: レビュー承認| H[soba:done + PR:soba:lgtm]
|
18
|
+
G -->|Claude: 修正要求| I[soba:requires-changes]
|
19
|
+
I -->|soba: 自動検出| K[soba:revising]
|
20
|
+
K -->|Claude: 修正対応| F
|
21
|
+
H -->|soba: 自動マージ| J[soba:merged]
|
22
|
+
J -->|次のキューイング| A
|
23
|
+
```
|
24
|
+
|
25
|
+
## 計画フェーズ
|
26
|
+
|
27
|
+
### 1. Issue検出
|
28
|
+
- **対象ラベル**: `soba:todo`
|
29
|
+
- **検出方法**: 定期的なGitHub Issue監視
|
30
|
+
- **選定基準**: Issue番号が最も若いものを1件抽出
|
31
|
+
- **実行主体**: **soba CLI**
|
32
|
+
|
33
|
+
### 2. キューイング・計画策定
|
34
|
+
- **【soba】** 複数の `soba:todo` から Issue番号が最も若いものを選択
|
35
|
+
- **【soba】** ラベルを `soba:todo` → `soba:queued` → `soba:planning` に変更
|
36
|
+
- **【soba】** Claude Codeプロセスを起動
|
37
|
+
- **【Claude】** Issueの内容を分析し、実装計画を策定
|
38
|
+
- **【Claude】** 策定完了後、ラベルを `soba:planning` → `soba:ready` に変更
|
39
|
+
|
40
|
+
## 実装フェーズ
|
41
|
+
|
42
|
+
### 1. Issue検出
|
43
|
+
- **対象ラベル**: `soba:ready`
|
44
|
+
- **検出方法**: 定期的なGitHub Issue監視
|
45
|
+
- **選定基準**: Issue番号が最も若いものを1件抽出
|
46
|
+
- **実行主体**: **soba CLI**
|
47
|
+
|
48
|
+
### 2. 実装作業
|
49
|
+
- **【soba】** ラベルを `soba:ready` → `soba:doing` に変更
|
50
|
+
- **【soba】** Claude Codeプロセスを起動
|
51
|
+
- **【Claude】** 以下を自動実行:
|
52
|
+
- Issueの実装
|
53
|
+
- セルフレビュー
|
54
|
+
- Pull Request作成
|
55
|
+
- **【Claude】** 完了後、ラベルを `soba:doing` → `soba:review-requested` に変更
|
56
|
+
|
57
|
+
## レビューフェーズ
|
58
|
+
|
59
|
+
### 1. Issue検出
|
60
|
+
- **対象ラベル**: `soba:review-requested`
|
61
|
+
- **検出方法**: 定期的なGitHub Issue監視
|
62
|
+
- **選定基準**: Issue番号が最も若いものを1件抽出
|
63
|
+
- **実行主体**: **soba CLI**
|
64
|
+
|
65
|
+
### 2. レビュー実施
|
66
|
+
- **【soba】** ラベルを `soba:review-requested` → `soba:reviewing` に変更
|
67
|
+
- **【soba】** Claude Codeプロセスを起動
|
68
|
+
- **【Claude】** PRの内容をレビューし、以下を実行:
|
69
|
+
- コード品質のチェック
|
70
|
+
- テスト実行状況の確認
|
71
|
+
- セキュリティ観点でのチェック
|
72
|
+
- レビューコメントの投稿
|
73
|
+
- **【Claude】** レビュー結果に応じてラベルを変更:
|
74
|
+
- 承認: Issueラベル `soba:reviewing` → `soba:done`、PRに `soba:lgtm` ラベル付与
|
75
|
+
- 修正要求: Issueラベル `soba:reviewing` → `soba:requires-changes`
|
76
|
+
|
77
|
+
## 修正フェーズ
|
78
|
+
|
79
|
+
### 1. Issue検出
|
80
|
+
- **対象ラベル**: `soba:requires-changes`
|
81
|
+
- **検出方法**: 定期的なGitHub Issue監視
|
82
|
+
- **選定基準**: Issue番号が最も若いものを1件抽出
|
83
|
+
- **実行主体**: **soba CLI**
|
84
|
+
|
85
|
+
### 2. 修正対応
|
86
|
+
- **【soba】** ラベルを `soba:requires-changes` → `soba:revising` に変更
|
87
|
+
- **【soba】** Claude Codeプロセスを起動
|
88
|
+
- **【Claude】** レビューコメントを確認し、以下を実行:
|
89
|
+
- 指摘事項への対応実施
|
90
|
+
- テストの修正・追加
|
91
|
+
- コードの改善
|
92
|
+
- **【Claude】** 修正完了後、ラベルを `soba:revising` → `soba:review-requested` に変更
|
93
|
+
|
94
|
+
## マージフェーズ
|
95
|
+
|
96
|
+
### 1. PR検出
|
97
|
+
- **対象ラベル**: PRの `soba:lgtm` ラベル
|
98
|
+
- **検出方法**: 定期的なGitHub PR監視
|
99
|
+
- **選定基準**: `soba:lgtm` ラベルが付いた全てのPR
|
100
|
+
- **実行主体**: **soba CLI**
|
101
|
+
|
102
|
+
### 2. 自動マージ実施
|
103
|
+
- **【soba】** PRのマージ可能状態を確認:
|
104
|
+
- CIが全てパス
|
105
|
+
- コンフリクトなし
|
106
|
+
- マージ可能状態
|
107
|
+
- **【soba】** 条件を満たすPRを自動的にマージ(squash merge)
|
108
|
+
- **【soba】** マージ後の処理:
|
109
|
+
- 関連するIssueを自動クローズ
|
110
|
+
- Issueに `soba:merged` ラベルを付与
|
111
|
+
- 作業ブランチを削除
|
112
|
+
|
113
|
+
## ラベル定義
|
114
|
+
|
115
|
+
### Issueラベル(状態管理)
|
116
|
+
|
117
|
+
| ラベル | 状態 | 説明 | 変更主体 |
|
118
|
+
|--------|------|------|----------|
|
119
|
+
| `soba:todo` | 待機 | 新規Issue、計画待ち(複数設定可) | - |
|
120
|
+
| `soba:queued` | キュー選択 | 優先度判定で選択済み(1つのみ) | soba → |
|
121
|
+
| `soba:planning` | 計画中 | Claude Codeが計画策定中(1つのみ) | soba → |
|
122
|
+
| `soba:ready` | 準備完了 | 計画策定済み、実装待ち | Claude → |
|
123
|
+
| `soba:doing` | 実装中 | Claude Codeが実装作業中(1つのみ) | soba → |
|
124
|
+
| `soba:review-requested` | レビュー待ち | PR作成済み、レビュー待ち | Claude → |
|
125
|
+
| `soba:reviewing` | レビュー中 | Claude Codeがレビュー実施中(1つのみ) | soba → |
|
126
|
+
| `soba:done` | 完了 | レビュー承認、マージ可能 | Claude → |
|
127
|
+
| `soba:requires-changes` | 修正要求 | レビューで修正が必要と判断 | Claude → |
|
128
|
+
| `soba:revising` | 修正中 | Claude Codeが修正対応中(1つのみ) | soba → |
|
129
|
+
| `soba:merged` | マージ済み | PRがマージされ、Issueクローズ済み | soba → |
|
130
|
+
|
131
|
+
### PRラベル(マージ判定)
|
132
|
+
|
133
|
+
| ラベル | 状態 | 説明 | 変更主体 |
|
134
|
+
|--------|------|------|----------|
|
135
|
+
| `soba:lgtm` | 承認済み | レビュー承認、自動マージ対象 | Claude → |
|
136
|
+
|
137
|
+
## 自動化のメリット
|
138
|
+
|
139
|
+
1. **継続的な進捗**: Issueが自動的に処理され、開発が停滞しない
|
140
|
+
2. **一貫性**: 同じプロセスで全てのIssueを処理
|
141
|
+
3. **効率化**: 手動でのラベル変更やプロセス起動が不要
|
142
|
+
4. **優先順位管理**: Issue番号順による明確な処理順序
|
143
|
+
5. **厳密な排他制御**: 常に1つのIssueのみがアクティブ処理される
|
@@ -0,0 +1,10 @@
|
|
1
|
+
# Development Documents
|
2
|
+
|
3
|
+
## ドキュメント一覧
|
4
|
+
|
5
|
+
- `architecture.md`: soba CLIのアーキテクチャ設計書(レイヤー構成、コンポーネント設計、ディレクトリ構造)
|
6
|
+
- `implementation-guide.md`: 実装ガイド(段階的な実装手順、ベストプラクティス、サンプルコード)
|
7
|
+
- `coding-standards.md`: コーディング規約(命名規則、スタイルガイド、Rubocop設定、レビューチェックリスト)
|
8
|
+
- `testing-strategy.md`: テスト戦略(テストピラミッド、各種テストの実装方法、カバレッジ目標)
|
9
|
+
- `distribution.md`: 配布戦略(配布方法は検討中)
|
10
|
+
- `tmux-management.md`: tmux管理機能(セッション管理、ペイン操作、自動クリーンアップ)
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# soba CLI アーキテクチャ設計書
|
2
|
+
|
3
|
+
## 概要
|
4
|
+
|
5
|
+
GitHub IssueとClaude Codeを連携させる自律的ワークフロー実行ツールのアーキテクチャ。
|
6
|
+
|
7
|
+
## レイヤー構成
|
8
|
+
|
9
|
+
```
|
10
|
+
┌─────────────────────────────────────┐
|
11
|
+
│ CLI (GLI) │ → コマンドインターフェース
|
12
|
+
├─────────────────────────────────────┤
|
13
|
+
│ Commands │ → コマンド処理
|
14
|
+
├─────────────────────────────────────┤
|
15
|
+
│ Services │ → ビジネスロジック
|
16
|
+
├─────────────────────────────────────┤
|
17
|
+
│ Domain │ → ドメインモデル
|
18
|
+
├─────────────────────────────────────┤
|
19
|
+
│ Infrastructure │ → 外部連携
|
20
|
+
└─────────────────────────────────────┘
|
21
|
+
```
|
22
|
+
|
23
|
+
## ディレクトリ構造
|
24
|
+
|
25
|
+
```
|
26
|
+
soba/
|
27
|
+
├── bin/soba # 実行ファイル
|
28
|
+
├── lib/soba/
|
29
|
+
│ ├── cli/ # CLIコマンド定義
|
30
|
+
│ ├── commands/ # コマンド実装
|
31
|
+
│ ├── services/ # ビジネスロジック
|
32
|
+
│ ├── domain/ # エンティティ、値オブジェクト
|
33
|
+
│ └── infrastructure/ # GitHub/Claude API連携
|
34
|
+
├── spec/ # テスト
|
35
|
+
└── config/ # 設定ファイル
|
36
|
+
```
|
37
|
+
|
38
|
+
## 主要コンポーネント
|
39
|
+
|
40
|
+
| コンポーネント | ライブラリ | 用途 |
|
41
|
+
|-------------|----------|------|
|
42
|
+
| CLI | GLI | コマンドライン処理 |
|
43
|
+
| DI | dry-container | 依存性注入 |
|
44
|
+
| HTTP | Faraday + Octokit | API通信 |
|
45
|
+
| 非同期 | concurrent-ruby | 並行処理 |
|
46
|
+
| ログ | semantic_logger | ログ出力 |
|
47
|
+
|
48
|
+
## データフロー
|
49
|
+
|
50
|
+
```
|
51
|
+
User → CLI → Command → Service → Domain
|
52
|
+
↓
|
53
|
+
Infrastructure → External API
|
54
|
+
```
|
55
|
+
|
56
|
+
## 設定ファイル
|
57
|
+
|
58
|
+
```yaml
|
59
|
+
# ~/.soba/config.yml
|
60
|
+
github:
|
61
|
+
token: ${GITHUB_TOKEN}
|
62
|
+
repository: owner/repo
|
63
|
+
|
64
|
+
claude:
|
65
|
+
api_key: ${CLAUDE_API_KEY}
|
66
|
+
|
67
|
+
workflow:
|
68
|
+
interval: 60
|
69
|
+
```
|
@@ -0,0 +1,152 @@
|
|
1
|
+
# soba CLI コーディング規約
|
2
|
+
|
3
|
+
## 基本原則
|
4
|
+
|
5
|
+
1. **可読性優先** - シンプルで理解しやすいコード
|
6
|
+
2. **Ruby Way** - Rubyの慣習に従う
|
7
|
+
3. **一貫性** - プロジェクト全体で統一
|
8
|
+
|
9
|
+
## 命名規則
|
10
|
+
|
11
|
+
| 種類 | 規則 | 例 |
|
12
|
+
|-----|------|-----|
|
13
|
+
| ファイル | snake_case | `issue_monitor.rb` |
|
14
|
+
| クラス | PascalCase | `IssueMonitor` |
|
15
|
+
| メソッド | snake_case | `fetch_issues` |
|
16
|
+
| 定数 | SCREAMING_SNAKE | `MAX_RETRIES` |
|
17
|
+
| 述語メソッド | 疑問符付き | `valid?` |
|
18
|
+
|
19
|
+
## ファイル構造
|
20
|
+
|
21
|
+
```ruby
|
22
|
+
# frozen_string_literal: true
|
23
|
+
|
24
|
+
require 'standard_library'
|
25
|
+
require_relative '../domain/issue'
|
26
|
+
|
27
|
+
module Soba
|
28
|
+
class IssueMonitor
|
29
|
+
# クラス実装
|
30
|
+
end
|
31
|
+
end
|
32
|
+
```
|
33
|
+
|
34
|
+
### require規則
|
35
|
+
|
36
|
+
- **相対パス**: 同一プロジェクト内のファイルは`require_relative`を使用
|
37
|
+
- **絶対パス禁止**: `require 'soba/services/foo'`は使わない(パスエラーの原因)
|
38
|
+
- **外部gem**: `require 'gem_name'`を使用
|
39
|
+
|
40
|
+
### GLIコマンド構造
|
41
|
+
|
42
|
+
```ruby
|
43
|
+
# bin/soba
|
44
|
+
#!/usr/bin/env ruby
|
45
|
+
require 'gli'
|
46
|
+
|
47
|
+
include GLI::App
|
48
|
+
|
49
|
+
desc 'Global option'
|
50
|
+
flag [:c, :config]
|
51
|
+
|
52
|
+
command :issue do |c|
|
53
|
+
c.action do |global, options, args|
|
54
|
+
# コマンド実装
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
exit run(ARGV)
|
59
|
+
```
|
60
|
+
|
61
|
+
## クラス設計
|
62
|
+
|
63
|
+
```ruby
|
64
|
+
class IssueMonitor
|
65
|
+
attr_reader :client
|
66
|
+
|
67
|
+
def initialize(client)
|
68
|
+
@client = client
|
69
|
+
end
|
70
|
+
|
71
|
+
def start
|
72
|
+
validate!
|
73
|
+
monitor_loop
|
74
|
+
end
|
75
|
+
|
76
|
+
private
|
77
|
+
|
78
|
+
def validate!
|
79
|
+
raise ConfigError unless valid?
|
80
|
+
end
|
81
|
+
end
|
82
|
+
```
|
83
|
+
|
84
|
+
## メソッド設計
|
85
|
+
|
86
|
+
- 10行以内を目安
|
87
|
+
- 引数は3個まで(オプションハッシュ推奨)
|
88
|
+
- ガード節で早期リターン
|
89
|
+
|
90
|
+
```ruby
|
91
|
+
def process(issue)
|
92
|
+
return unless issue.valid?
|
93
|
+
return if issue.closed?
|
94
|
+
|
95
|
+
perform_processing(issue)
|
96
|
+
end
|
97
|
+
```
|
98
|
+
|
99
|
+
## エラーハンドリング
|
100
|
+
|
101
|
+
```ruby
|
102
|
+
module Soba
|
103
|
+
class Error < StandardError; end
|
104
|
+
class ConfigError < Error; end
|
105
|
+
end
|
106
|
+
|
107
|
+
def fetch_issue(id)
|
108
|
+
client.issue(id)
|
109
|
+
rescue Octokit::NotFound
|
110
|
+
nil
|
111
|
+
end
|
112
|
+
```
|
113
|
+
|
114
|
+
## Rubocop設定(主要項目)
|
115
|
+
|
116
|
+
```yaml
|
117
|
+
AllCops:
|
118
|
+
TargetRubyVersion: 3.2
|
119
|
+
|
120
|
+
Layout/LineLength:
|
121
|
+
Max: 100
|
122
|
+
|
123
|
+
Metrics/MethodLength:
|
124
|
+
Max: 15
|
125
|
+
|
126
|
+
Style/StringLiterals:
|
127
|
+
EnforcedStyle: double_quotes
|
128
|
+
```
|
129
|
+
|
130
|
+
## テストコード
|
131
|
+
|
132
|
+
```ruby
|
133
|
+
RSpec.describe IssueMonitor do
|
134
|
+
let(:monitor) { described_class.new(client) }
|
135
|
+
|
136
|
+
describe '#start' do
|
137
|
+
context 'when valid' do
|
138
|
+
it 'starts monitoring' do
|
139
|
+
expect(monitor).to receive(:monitor_loop)
|
140
|
+
monitor.start
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
```
|
146
|
+
|
147
|
+
## コードレビューチェックリスト
|
148
|
+
|
149
|
+
- [ ] 命名規則に従っているか
|
150
|
+
- [ ] 単一責任の原則を守っているか
|
151
|
+
- [ ] テストが書かれているか
|
152
|
+
- [ ] エラーハンドリングが適切か
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# soba CLI 配布戦略
|
2
|
+
|
3
|
+
## 概要
|
4
|
+
|
5
|
+
soba CLIの配布方法は現在検討中です。
|
6
|
+
|
7
|
+
## 配布方法(検討中)
|
8
|
+
|
9
|
+
現在、以下の配布方法を検討しています:
|
10
|
+
|
11
|
+
1. **gem配布**
|
12
|
+
- RubyGemsによる標準的な配布
|
13
|
+
- `gem install soba`でインストール可能
|
14
|
+
|
15
|
+
2. **スタンドアロンバイナリ**
|
16
|
+
- Ruby環境不要の単一実行ファイル
|
17
|
+
- 各プラットフォーム向けに最適化
|
18
|
+
|
19
|
+
3. **パッケージマネージャ**
|
20
|
+
- Homebrew(macOS/Linux)
|
21
|
+
- Scoop/Chocolatey(Windows)
|
22
|
+
- APT/YUM(Linux)
|
23
|
+
|
24
|
+
## 今後の計画
|
25
|
+
|
26
|
+
配布戦略の詳細は、プロジェクトの成熟度とユーザーのニーズに応じて決定される予定です。
|
@@ -0,0 +1,103 @@
|
|
1
|
+
# soba CLI 実装ガイド
|
2
|
+
|
3
|
+
## 実装フェーズ
|
4
|
+
|
5
|
+
### Phase 1: 基盤構築(1週目)
|
6
|
+
|
7
|
+
```bash
|
8
|
+
# Gemfile作成
|
9
|
+
bundle init
|
10
|
+
bundle add gli dry-container dry-auto_inject faraday octokit
|
11
|
+
bundle add --group development,test rspec webmock rubocop
|
12
|
+
```
|
13
|
+
|
14
|
+
基本ファイル:
|
15
|
+
- `bin/soba` - 実行ファイル
|
16
|
+
- `lib/soba.rb` - エントリポイント
|
17
|
+
- `lib/soba/container/container.rb` - DI設定
|
18
|
+
|
19
|
+
### Phase 2: CLIコマンド(2週目)
|
20
|
+
|
21
|
+
```ruby
|
22
|
+
# bin/soba
|
23
|
+
#!/usr/bin/env ruby
|
24
|
+
require 'gli'
|
25
|
+
require 'soba'
|
26
|
+
|
27
|
+
include GLI::App
|
28
|
+
|
29
|
+
program_desc 'GitHub Issue to Claude Code workflow automation'
|
30
|
+
version Soba::VERSION
|
31
|
+
|
32
|
+
desc 'Manage issues'
|
33
|
+
command :issue do |c|
|
34
|
+
c.desc 'List issues'
|
35
|
+
c.command :list do |list|
|
36
|
+
list.action do |global_options, options, args|
|
37
|
+
Soba::Commands::Issue::List.new.execute(args[0])
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
exit run(ARGV)
|
43
|
+
```
|
44
|
+
|
45
|
+
実装順序:
|
46
|
+
1. `config` - 設定確認
|
47
|
+
2. `issue list` - 一覧取得
|
48
|
+
3. `issue watch` - 監視機能
|
49
|
+
|
50
|
+
### Phase 3: ドメインモデル(3週目)
|
51
|
+
|
52
|
+
```ruby
|
53
|
+
# lib/soba/domain/entities/issue.rb
|
54
|
+
module Soba
|
55
|
+
class Issue
|
56
|
+
attr_reader :id, :title, :state
|
57
|
+
|
58
|
+
def open?
|
59
|
+
state == 'open'
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
```
|
64
|
+
|
65
|
+
### Phase 4: 外部連携(4週目)
|
66
|
+
|
67
|
+
```ruby
|
68
|
+
# lib/soba/infrastructure/github/client.rb
|
69
|
+
module Soba
|
70
|
+
class GitHubClient
|
71
|
+
def initialize(token:)
|
72
|
+
@octokit = Octokit::Client.new(access_token: token)
|
73
|
+
end
|
74
|
+
|
75
|
+
def issues(repo)
|
76
|
+
@octokit.issues(repo)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
```
|
81
|
+
|
82
|
+
## Gem構成
|
83
|
+
|
84
|
+
```ruby
|
85
|
+
# soba.gemspec
|
86
|
+
Gem::Specification.new do |spec|
|
87
|
+
spec.name = "soba"
|
88
|
+
spec.version = "0.1.0"
|
89
|
+
spec.files = Dir["lib/**/*", "bin/*"]
|
90
|
+
spec.executables = ["soba"]
|
91
|
+
spec.add_dependency "gli", "~> 2.21"
|
92
|
+
end
|
93
|
+
```
|
94
|
+
|
95
|
+
## Docker化
|
96
|
+
|
97
|
+
```dockerfile
|
98
|
+
FROM ruby:3.2-slim
|
99
|
+
WORKDIR /app
|
100
|
+
COPY . .
|
101
|
+
RUN bundle install
|
102
|
+
ENTRYPOINT ["bin/soba"]
|
103
|
+
```
|
@@ -0,0 +1,128 @@
|
|
1
|
+
# soba CLI テスト戦略
|
2
|
+
|
3
|
+
## テストピラミッド
|
4
|
+
|
5
|
+
```
|
6
|
+
/\
|
7
|
+
/ \ E2E (5%)
|
8
|
+
/────\ 統合テスト (20%)
|
9
|
+
/──────\
|
10
|
+
/────────\ ユニットテスト (75%)
|
11
|
+
```
|
12
|
+
|
13
|
+
## テストレベル
|
14
|
+
|
15
|
+
### 1. ユニットテスト
|
16
|
+
|
17
|
+
個別クラス・メソッドの動作検証。実実装を使用して正確性を確保。
|
18
|
+
|
19
|
+
```ruby
|
20
|
+
RSpec.describe Issue do
|
21
|
+
describe '#priority' do
|
22
|
+
let(:issue) { described_class.new(labels: ['critical']) }
|
23
|
+
|
24
|
+
it 'returns high for critical issues' do
|
25
|
+
expect(issue.priority).to eq(:high)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
```
|
30
|
+
|
31
|
+
### 2. 統合テスト
|
32
|
+
|
33
|
+
コンポーネント間連携とAPI連携の検証。VCRでHTTP記録。
|
34
|
+
|
35
|
+
```ruby
|
36
|
+
RSpec.describe GitHubClient, :vcr do
|
37
|
+
it 'fetches issues from repository' do
|
38
|
+
issues = client.fetch_issues('owner/repo')
|
39
|
+
expect(issues).to be_an(Array)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
```
|
43
|
+
|
44
|
+
### 3. E2Eテスト
|
45
|
+
|
46
|
+
CLIコマンド全体の動作確認。
|
47
|
+
|
48
|
+
```ruby
|
49
|
+
RSpec.describe 'CLI', type: :e2e do
|
50
|
+
it 'lists issues' do
|
51
|
+
output = `bin/soba issue list owner/repo`
|
52
|
+
expect($?).to be_success
|
53
|
+
expect(output).to include('Issues')
|
54
|
+
end
|
55
|
+
end
|
56
|
+
```
|
57
|
+
|
58
|
+
## テスト構成
|
59
|
+
|
60
|
+
```ruby
|
61
|
+
# spec/spec_helper.rb
|
62
|
+
require 'simplecov'
|
63
|
+
SimpleCov.start { minimum_coverage 90 }
|
64
|
+
|
65
|
+
RSpec.configure do |config|
|
66
|
+
config.include FactoryBot::Syntax::Methods
|
67
|
+
config.order = :random
|
68
|
+
end
|
69
|
+
```
|
70
|
+
|
71
|
+
## モック戦略
|
72
|
+
|
73
|
+
**重要: モックの利用は外部のAPI連携のみに限定する。それ以外のテスト時は必ず実実装を利用する。**
|
74
|
+
|
75
|
+
```ruby
|
76
|
+
# 外部API連携のみモック化
|
77
|
+
module MockHelpers
|
78
|
+
def stub_github_api_response
|
79
|
+
stub_request(:get, /api.github.com/).
|
80
|
+
to_return(status: 200, body: '[]', headers: {})
|
81
|
+
end
|
82
|
+
end
|
83
|
+
```
|
84
|
+
|
85
|
+
## VCR設定
|
86
|
+
|
87
|
+
```ruby
|
88
|
+
VCR.configure do |config|
|
89
|
+
config.cassette_library_dir = 'spec/fixtures/vcr'
|
90
|
+
config.hook_into :webmock
|
91
|
+
config.filter_sensitive_data('<TOKEN>') { ENV['GITHUB_TOKEN'] }
|
92
|
+
end
|
93
|
+
```
|
94
|
+
|
95
|
+
## CI/CD
|
96
|
+
|
97
|
+
```yaml
|
98
|
+
# .github/workflows/test.yml
|
99
|
+
name: Test
|
100
|
+
on: [push, pull_request]
|
101
|
+
|
102
|
+
jobs:
|
103
|
+
test:
|
104
|
+
runs-on: ubuntu-latest
|
105
|
+
steps:
|
106
|
+
- uses: actions/checkout@v3
|
107
|
+
- uses: ruby/setup-ruby@v1
|
108
|
+
with:
|
109
|
+
bundler-cache: true
|
110
|
+
- run: bundle exec rspec
|
111
|
+
```
|
112
|
+
|
113
|
+
## カバレッジ目標
|
114
|
+
|
115
|
+
| レイヤー | 目標 |
|
116
|
+
|---------|------|
|
117
|
+
| Domain | 95%+ |
|
118
|
+
| Services | 90%+ |
|
119
|
+
| Infrastructure | 85%+ |
|
120
|
+
| CLI | 80%+ |
|
121
|
+
|
122
|
+
## ベストプラクティス
|
123
|
+
|
124
|
+
- AAAパターン(Arrange, Act, Assert)
|
125
|
+
- 1テスト1アサーション
|
126
|
+
- テストの独立性確保
|
127
|
+
- 明確なテスト名
|
128
|
+
- 実実装の利用(外部API以外はモック化禁止)
|