51 テンプレート内蔵の .gitignore ジェネレーター CLI を Python で作った
きっかけ
新しいプロジェクトを始めるたびに同じことをやる。ディレクトリを作り、git init して、gitignore.io か GitHub のテンプレートピッカーで .gitignore を組み立てる。3クリック、スクロール、前のプロジェクトからのコピペ。動くが、キャリアを通じて何百回も繰り返す摩擦。
gitignore-gen はその摩擦を消すツール。51のテンプレートを内蔵し、gitignore-gen python node macos で重複排除済みの .gitignore を生成する。ネットワークリクエストなし、API キーなし、Python 標準ライブラリのみ。
🔗 GitHub: https://github.com/sen-ltd/gitignore-gen

使い方
# テンプレートを結合して stdout に出力
$ gitignore-gen python node macos
# ファイルに直接書き出し
$ gitignore-gen python node --output .gitignore
# 51 テンプレートの一覧
$ gitignore-gen --list
# キーワードでテンプレートを検索
$ gitignore-gen --search ide
エイリアス
誰も毎回 objective-c や sublimetext とは打ちたくない。40以上のエイリアスをサポート。
# 同じ意味
$ gitignore-gen py js mac
$ gitignore-gen python node macos
# IDE エイリアス
$ gitignore-gen idea # → jetbrains
$ gitignore-gen code # → vscode
# 言語エイリアス
$ gitignore-gen rs # → rust
$ gitignore-gen ts # → typescript
アーキテクチャ
3つのモジュールが明確な責務分離で構成されている。
テンプレートデータベース(src/templates.py)
テンプレート名から gitignore パターンのリストへの Python 辞書。
TEMPLATES: dict[str, list[str]] = {
"python": [
"# Python",
"__pycache__/",
"*.py[cod]",
"*$py.class",
"*.so",
# ... 30+ パターン
],
# ... 51 テンプレート
}
各テンプレートはコメントヘッダ(# Python、# Node.js 等)で始まる。マージ後の出力でどのテンプレートがどのパターンを提供したかが一目でわかる。
テンプレートを外部ファイルや GitHub API ではなく Python の辞書に埋め込んだ理由は3つ。
- オフライン動作 — 電車、飛行機、企業ファイアウォール内でもツールが動く
- 速度 — 辞書ルックアップはマイクロ秒、API コールは数百ミリ秒
- 信頼性 — API レート制限、認証トークン、DNS 解決エラーが存在しない
gitignore パターンは滅多に変わらない。Python は10年以上 __pycache__/ と *.pyc を使っている。Node は最初から node_modules/。
マージエンジン(src/merger.py)
テンプレート名のリストを受け取り、クリーンな .gitignore 文字列を生成する。
- エイリアスを正式名に解決
- テンプレートの重複排除(
python pythonと書いても1回だけ処理) - パターンの重複排除(Python と Node の両方が
.envを含んでいたら1つだけ出力) - セクションヘッダ(コメント行)は重複排除しない
- テンプレート間に空行を挿入
重複排除は「先勝ち」方式。Python と Node が両方 .env を含んでいる場合、Python セクションに残る(先にリストされたから)。これによりパターンが論理的なコンテキストから分離されず、6ヶ月後にファイルを読んだときにも各パターンの出所がわかる。
CLI(src/cli.py)
argparse を使い、外部依存なし。sys.exit() を直接呼ばず整数の exit code を返すので、テストで SystemExit をキャッチする必要がない。
--output はデフォルトで上書き、--append で追記モード。チームメンバーごとにエディタテンプレートを追加するときに便利。
テンプレートのカバレッジ
51テンプレートを6カテゴリに整理。
言語(27): Python, Node.js, Rust, Go, Java, PHP, Ruby, Swift, Kotlin, C, C++, Dart, Elixir, Haskell, Scala, R, Julia, Lua, Perl, TeX, C#, F#, TypeScript, Zig, Erlang, Clojure, Objective-C
ゲームエンジン(3): Unity, Unreal Engine, Godot
モバイル(3): Android, Xcode, Flutter
エディタ(5): JetBrains, VSCode, Vim, Emacs, Sublime Text
OS(3): macOS, Windows, Linux
ビルドツール(10): Terraform, Docker, CMake, Gradle, Maven, Bazel, Vagrant, Ansible, Rails, Next.js
各テンプレートはそのエコシステムで重要なパターンをキュレーションしている。Python テンプレートには __pycache__/ だけでなく、pytest(.pytest_cache/)、mypy(.mypy_cache/)、coverage(.coverage、htmlcov/)、tox、仮想環境(.venv/、venv/、ENV/)のパターンが含まれる。
テスト
32件の pytest テスト。
- テンプレート(12件): テンプレート数 >= 50、全テンプレートにエントリあり、コメントヘッダ開始、エイリアス解決、検索
- マージ(10件): 単一・複数テンプレート、重複排除(テンプレート内・テンプレート間)、セクションヘッダ保持、未知テンプレートエラー
- CLI(10件):
--list、--search、stdout 生成、--outputファイル書き込み、--append、不正テンプレート
マージの重複排除テストが特に重要。テンプレート間で共有されるパターンが出力に1回だけ現れること、セクションヘッダは常に保持されること、テンプレートの順序がどのセクションが共有パターンを「所有」するかに影響することを検証する。
実際のワークフロー
# 新しい Python Web プロジェクト
$ mkdir my-project && cd my-project
$ git init
$ gitignore-gen python node macos vscode --output .gitignore
$ git add .gitignore && git commit -m "initial commit"
# 後からチームメイト用に JetBrains パターンを追加
$ gitignore-gen jetbrains --output .gitignore --append
# Rust プロジェクト用のテンプレートを確認
$ gitignore-gen --search rust
学んだこと
テンプレートのキュレーションはコードを書くより大変。 マージエンジンは半日で書けた。51テンプレートを適切なパターンでキュレーションするのはもっとかかった。各言語エコシステムの慣習、ビルドツール、エディタ連携を知る必要がある。
重複排除には順序のセマンティクスが必要。 最初の実装は set で全パターンをアルファベット順に並べた。正しいが読めない。「先勝ち」方式にしたら論理的なグルーピングが保持された。
エイリアスは UX 機能。 エイリアスシステムはマージエンジンに複雑さをゼロ追加する(解決ステップの辞書引きだけ)。しかし gitignore-gen py js mac と打てることでユーザー体験が劇的に改善する。
ソースは GitHub にある。pytest だけでテストスイートが動き、python main.py で次の .gitignore を生成できる。