-
Notifications
You must be signed in to change notification settings - Fork 1
Code Structure Components
wikigenは単一の Go ソースファイル(main.go、1070行)で構成された実行可能プログラムである。本ページでは、主要なデータ型・構造体、キー関数、およびモジュール全体の構成を詳細に解説する。標準ライブラリのみを使用し、外部依存なしで実装されている点が特徴的な設計上の決断であり、アーキテクチャ & 設計ページと合わせて参照することで全体像を把握できる。
本ページが対象とするリポジトリは wikigen(main.go)の単一ファイル実装である。ビルド手順や環境構成については インストール & セットアップ を、CLI フラグの詳細は CLI 使用法 & コマンド を参照のこと。
go.mod(3行)でモジュール名 wikigen、Go バージョン 1.25.7 を宣言する。外部依存は一切なく、標準ライブラリのみを使用している。
Sources: main.go:1-17
package main
import (
"bytes"
"encoding/json"
"flag"
"fmt"
"log"
"os"
"os/exec"
"path/filepath"
"regexp"
"strings"
"sync"
"sync/atomic"
"time"
)main.go は論理的に以下の 9 セクションに分かれている。
| セクション | 行番号 | 説明 |
|---|---|---|
| インポート | 3–17 | 標準ライブラリのインポート |
| Progress 追跡 | 19–58 | 並行進捗管理 |
| データ型定義 | 60–112 | 主要構造体 |
| 入力バリデーション | 77–92 | セキュリティチェック |
| プロンプト & 言語 | 175–376 | Claude 向けプロンプト生成 |
| XML パース | 378–458 | 構造レスポンス解析 |
| エラー処理 & Wiki 生成 | 460–667 | コアロジック |
| リトライロジック | 741–877 | 失敗ページの再試行 |
| メインエントリポイント | 879–1069 | フラグ解析・オーケストレーション |
Sources: main.go:1-1070
type Progress struct {
mu sync.Mutex
totalItems int
doneItems int32
current map[string]string
}Sources: main.go:21-26
並列処理中の進捗をスレッドセーフに管理する。doneItems は sync/atomic パッケージで操作されるため、Mutex ロックなしで更新できる。current マップは実行中タスクの名前とステータスを保持し、ターミナルへの進捗バー表示に使用される。
メソッド一覧
| メソッド | 行番号 | 説明 |
|---|---|---|
newProgress(total int) |
28–30 | コンストラクタ |
set(name, status string) |
32–37 | タスクステータス更新(Mutex 保護) |
done(name string) |
39–45 | タスク完了・マップから削除 |
print() |
47–58 | 進捗バーをパーセンテージ付きで表示 |
Sources: main.go:28-58
type WikiPage struct {
ID string
Title string
Filename string
Description string
Content string
}Sources: main.go:62-68
Claude が返す XML 構造レスポンスから解析されたページ定義をメモリ内に保持する。Filename は GitHub Wiki 互換のハイフン区切り形式(例: Code-Structure-Components.md)となる。Content フィールドはフェーズ 2 のページ生成後に実際のファイル内容で埋められる。
type RepoEntry struct {
Project string
Repo string
}Sources: main.go:72-75
repos.txt の各行を解析した結果を保持する。Project はグループ名(スタンドアロンの場合は空文字列)、Repo は owner/repo 形式のリポジトリ識別子である。複数リポジトリの Wiki 生成については マルチリポジトリ Wiki 生成 を参照。
type WikiResult struct {
Project string `json:"project"`
Repos []string `json:"repos"`
OutputDir string `json:"output_dir"`
Pages []WikiPageResult `json:"pages"`
TotalPages int `json:"total_pages"`
Failed int `json:"failed"`
Duration string `json:"duration"`
Status string `json:"status"`
}
type WikiPageResult struct {
Title string `json:"title"`
Filename string `json:"filename"`
Size int `json:"size"`
Status string `json:"status"`
}Sources: main.go:96-112
-json フラグ有効時に標準出力へ書き出す JSON シリアライズ用の構造体である。WikiPageResult.Status は "ok"・"failed"・"pending" の 3 値を取る。JSON 出力の詳細は JSON 出力 & 構造化結果 を参照。
classDiagram
class Progress {
+sync.Mutex mu
+int totalItems
+int32 doneItems
+map current
+newProgress(total)
+set(name, status)
+done(name)
+print()
}
class WikiPage {
+string ID
+string Title
+string Filename
+string Description
+string Content
}
class RepoEntry {
+string Project
+string Repo
}
class WikiResult {
+string Project
+[]string Repos
+string OutputDir
+[]WikiPageResult Pages
+int TotalPages
+int Failed
+string Duration
+string Status
}
class WikiPageResult {
+string Title
+string Filename
+int Size
+string Status
}
WikiResult "1" --> "many" WikiPageResult : contains
WikiPage --> WikiPageResult : generates
Sources: main.go:116-143
func claudeCall(claudePath, model string, repoDirs []string,
systemPrompt, prompt, workDir string) (string, error)Claude CLI を -p(プロンプトモード)で起動する中心的な関数。実行引数の構成は以下の通り。
| 引数 | 説明 |
|---|---|
-p |
プロンプトモード(stdin から入力) |
--output-format text |
テキスト出力のみ |
--dangerously-skip-permissions |
ツール権限チェックをスキップ |
--model [model] |
モデル指定(空なら省略) |
--add-dir [dir] |
リポジトリディレクトリ追加(繰り返し可能) |
--system-prompt [prompt] |
システムメッセージ(空なら省略) |
--stdin |
stdin からプロンプトを読み込む |
Claude へのプロンプトは bytes.Buffer を介して cmd.Stdin に渡される。戻り値はトリムされた標準出力文字列。Claude Code 連携の詳細は Claude Code 連携 を参照。
Sources: main.go:474-638
func generateWiki(claudePath, model string, projectName string,
repos []string, token, language, outputDir, cloneDir string,
pageParallel int, dryRun bool, localDir string,
progress *Progress) (*WikiResult, error)Wiki 生成の全フェーズを統括する中心関数。実行フローは以下の 4 フェーズで構成される。
flowchart TD
A[Phase 0: リポジトリセットアップ] --> B[Phase 1: 構造決定]
B --> C{dry-run?}
C -->|Yes| D[構造のみ返却]
C -->|No| E[Phase 3: ページ並列生成]
E --> F[Phase 4: 結果集計]
subgraph Phase0
A1[リポジトリ検証] --> A2[git clone / local使用]
A2 --> A3[repoDirs収集]
end
subgraph Phase1
B1[structurePrompt生成] --> B2[claudeCall実行]
B2 --> B3[XML解析・parsePages]
B3 --> B4[Home.md / Sidebar生成]
end
subgraph Phase3
E1[セマフォ作成] --> E2[goroutine起動]
E2 --> E3[最大3回リトライ]
E3 --> E4[ファイルサイズ検証]
end
Phase 0: リポジトリセットアップ(lines 481–517)
-
-localフラグがある場合はローカルディレクトリをそのまま使用 - それ以外は
gitClone()を呼び出し depth=1 で取得
Phase 1: 構造決定(lines 526–549)
-
structurePrompt()を生成しclaudeCall()へ送信 -
cleanXMLResponse()→parsePages()で WikiPage スライスを生成 -
writeHomeAndSidebar()で Home.md と _Sidebar.md を即時生成
Phase 2: ドライランチェック(lines 557–563)
-
-dry-run設定時は構造情報のみを返却して終了
Phase 3: 並列ページ生成(lines 565–617)
-
pageParallel容量のセマフォで同時実行数を制御 - 各ページで最大 3 回のリトライを実施
- 100 バイト未満のファイルは失敗と判定
Phase 4: 結果集計(lines 619–637)
- ファイルサイズで ok/failed を判定
-
WikiResultを返却
Sources: main.go:399-434
func parsePages(xml string) []WikiPageClaude が返す XML 構造レスポンスからページ定義を抽出する。<page id="..."> 要素を反復処理し、タグ内の title・filename・description を抽出する。filename が省略された場合は titleToFilename() でタイトルから自動生成する。
// titleToFilename の変換例
func titleToFilename(title string) string {
r := strings.NewReplacer(
" ", "-", "/", "-", ":", "-",
"(", "-", ")", "-",
" ", "-", "・", "-",
)
...
}Sources: main.go:451-458
Sources: main.go:640-667
func writeHomeAndSidebar(wikiDir, projectName, structureContent string,
allPages []WikiPage, repos []string)GitHub Wiki 特有の 2 ファイルを生成する。
Home.md の構成:
-
# {projectName}タイトル - XML から抽出した説明文
- リポジトリ一覧(複数リポジトリの場合)
- 生成タイムスタンプ
- 全ページへのリンク一覧
_Sidebar.md の構成:
- Home へのリンク
- 全ページへのリンク(GitHub Wiki の左サイドバーナビゲーション用)
出力ファイル形式の詳細は 出力フォーマット & Wiki 構造 を参照。
Sources: main.go:674-690
func parseRepoList(lines []string) (standalone []RepoEntry,
groups map[string][]string)repos.txt の各行を解析し、スタンドアロンとグループの 2 種類に分類する。
| 入力フォーマット | 分類 | 説明 |
|---|---|---|
owner/repo |
standalone | 単独 Wiki |
project:owner/repo |
groups | プロジェクトグループ Wiki |
# コメント |
スキップ | コメント行 |
| 空行 | スキップ | 無視 |
flowchart TD
A[lines 入力] --> B{行の形式?}
B -->|空行・コメント| C[スキップ]
B -->|project:repo 形式| D[groups マップに追加]
B -->|owner/repo 形式| E[standalone スライスに追加]
D --> F[戻り値: standalone, groups]
E --> F
Sources: main.go:77-92
var validRepoPattern = regexp.MustCompile(`^[a-zA-Z0-9._-]+/[a-zA-Z0-9._-]+$`)
func validateRepo(repo string) error {
if strings.Contains(repo, "..") {
return fmt.Errorf("invalid repo: path traversal detected: %s", repo)
}
for _, c := range []string{";", "&", "|", "`", "$", "(", ")", "{", "}", "[", "]", "!", "~"} {
if strings.Contains(repo, c) {
return fmt.Errorf("invalid repo: dangerous character in: %s", repo)
}
}
if !validRepoPattern.MatchString(repo) {
return fmt.Errorf("invalid repo format (expected owner/repo): %s", repo)
}
return nil
}3 段階のバリデーションを実施する。セキュリティの詳細は 入力バリデーション & セキュリティ を参照。
- パストラバーサル検出(
..の存在チェック) - 危険文字ブロック(
;,&,|等) -
owner/repo形式の正規表現マッチ
Sources: main.go:380-397
func cleanXMLResponse(content string) stringClaude の応答からマークダウンコードフェンス(バックティック)・</wiki_structure> タグ以降のテキスト・思考タグ(/think、/no_think)を除去する。これにより XML パーサーへの入力を安全な形式に変換する。
Sources: main.go:462-470
func appendError(dir, msg string)_errors.log にタイムスタンプ付きのエラーメッセージを追記する。ファイルが存在しない場合は新規作成、存在する場合は追記する。エラー処理の詳細は エラー処理 & リトライメカニズム を参照。
Sources: main.go:743-877
func retryFailedPages(claudePath, model, language, outputDir,
cloneDir string, pageParallel int)-retry フラグ有効時に呼び出される回復メカニズム。出力ディレクトリをスキャンし「Content generation failed」を含む、もしくは 200 バイト未満のページを特定して再生成する。Home.md からページ定義を再構築してクロスリンク情報を維持する。
Sources: main.go:694-739
| 関数 | 行番号 | 説明 |
|---|---|---|
envOrDefault(key, fallback) |
694–699 | 環境変数取得(フォールバック付き) |
envOrDefaultInt(key, fallback) |
701–710 | 整数環境変数解析 |
envOrDefaultBool(key, fallback) |
712–717 | ブール環境変数解析 |
loadEnvFile() |
719–739 |
.env / .env.local 読み込み |
loadEnvFile() は既に設定済みの環境変数を上書きしない(.env ファイルよりも実環境変数を優先)。設定の詳細は 設定 & 環境変数 を参照。
Sources: main.go:175-181
Claude に対して生の XML のみを返すよう指示するシステムプロンプト。マークダウンのコードフェンスなどの装飾を禁止する。
Sources: main.go:183-273
func structurePrompt(projectName string, repos []string,
language string) stringWiki 構造設計フェーズで使用するプロンプト。Claude に対して Read・Grep・Glob・Bash ツールでリポジトリを解析し、実際に存在するコードに基づくページ定義を XML 形式で返すよう指示する。
Sources: main.go:275-362
func pagePrompt(page WikiPage, allPages []WikiPage,
projectName string, repos []string, language string) string個別ページ生成フェーズで使用するプロンプト。ページタイトル・説明・出力言語・クロスリンク情報・品質要件(コード引用必須・推測禁止)を含む。
Sources: main.go:364-376
言語コードを人間可読な名称にマッピングする。サポート言語の詳細は 言語サポート & ローカライゼーション を参照。
func languageName(code string) string {
switch code {
case "ja": return "Japanese"
case "en": return "English"
case "zh": return "Mandarin Chinese"
// ...
}
}Sources: main.go:881-1069
main() 関数は 7 フェーズで構成される。
flowchart TD
A[Phase 1: 初期化] --> B[Phase 2: リトライモード確認]
B -->|retry フラグあり| C[retryFailedPages 実行・終了]
B -->|通常実行| D[Phase 3: 入力収集]
D --> E[Phase 4: タスク構築]
E --> F[Phase 5: バリデーション]
F --> G[Phase 6: 並列実行]
G --> H[Phase 7: 出力]
subgraph 並列実行
G1[セマフォ作成] --> G2[goroutine起動]
G2 --> G3[generateWiki呼び出し]
G3 --> G4[結果収集]
end
フラグ定義一覧(lines 884–917)
| フラグ | 型 | デフォルト | 説明 |
|---|---|---|---|
-retry |
bool | false | 失敗ページのみ再試行 |
-dry-run |
bool | false | 構造確認のみ(生成なし) |
-json |
bool | false | JSON を標準出力に出力 |
-local |
string | "" |
ローカルディレクトリ指定 |
-f |
string | "" |
リポジトリリストファイル |
-r |
string | "" |
カンマ区切りリポジトリ |
-token |
string | $GITHUB_TOKEN |
GitHub PAT |
-model |
string | $CLAUDE_MODEL |
Claude モデル指定 |
-lang |
string | ja |
出力言語 |
-o |
string | ./wiki-output |
出力ディレクトリ |
-clone-dir |
string | ./.repos |
一時クローンディレクトリ |
-claude |
string | claude |
Claude バイナリパス |
-p |
int |
$WIKI_PARALLEL(1) |
プロジェクト並列数 |
-pp |
int |
$WIKI_PAGE_PARALLEL(3) |
ページ並列数 |
-log |
string | "" |
ログファイルパス |
Sources: main.go:884-917
flowchart TD
A[main: プロジェクト一覧] --> B[セマフォ: -p 容量]
B --> C1[goroutine: プロジェクト1]
B --> C2[goroutine: プロジェクト2]
B --> C3[goroutine: プロジェクトN]
C1 --> D[generateWiki]
D --> E[セマフォ: -pp 容量]
E --> F1[goroutine: ページ1]
E --> F2[goroutine: ページ2]
E --> F3[goroutine: ページM]
F1 --> G[claudeCall]
F2 --> G
F3 --> G
G --> H[atomic: doneItems++]
H --> I[Progress.print]
2 レベルの並行処理が実装されている。プロジェクトレベル(-p フラグ)とページレベル(-pp フラグ)のそれぞれにセマフォが設けられ、Claude API へのリクエスト数を制御する。並行処理の詳細は 並列処理 & 並行性 を参照。
Sources: main.go:147-171
func gitClone(repoURL, token, destDir string) error2 パスの実装で構成される。
-
リポジトリが既存の場合:
git pull --ff-onlyで更新 -
新規クローンの場合:
-
PAT 認証:
https://[token]@github.com/owner/repo形式の HTTPS URL -
SSH 認証:
git@github.com:owner/repo.git形式 -
git clone --depth=1 --single-branchで軽量取得
-
PAT 認証:
認証方式の詳細は リポジトリアクセス & 認証 を参照。
- アーキテクチャ & 設計 — 高レベルアーキテクチャ図と 2 フェーズアプローチ
- Claude Code 連携 — claudeCall の詳細と XML プロンプト仕様
- 並列処理 & 並行性 — goroutine とセマフォによる並行処理
- 入力バリデーション & セキュリティ — validateRepo の脅威モデル
- エラー処理 & リトライメカニズム — appendError と retryFailedPages の動作
- 出力フォーマット & Wiki 構造 — writeHomeAndSidebar の出力仕様
- JSON 出力 & 構造化結果 — WikiResult / WikiPageResult の JSON スキーマ
- CLI 使用法 & コマンド — main() で定義される全フラグのリファレンス
- 設定 & 環境変数 — envOrDefault ヘルパーと .env ファイルの仕様
- 言語サポート & ローカライゼーション — languageName 関数のサポート言語
- System Overview
- Architecture & Design
- CLI Usage & Commands
- Configuration & Environment
- Input Formats & Repository Configuration
- Authentication & Git Integration
- Output Format & Wiki Structure
- Error Handling & Retry Mechanism
- Parallel Processing & Performance
- Input Validation & Security
- Build & Deployment
- Claude Code Integration
- Wiki Generation Processing Flow
- Multi-Repository Wiki Support
- Progress Tracking & Output Modes