本記事の構成および論理分析にはAI(人工知能)を使用しています。情報の正確性は、システム管理者(UNIXユーザー)による手動検証済みです。
第4回 | 育てた相棒を Git で公開する。Term-gotchi を壊さず更新できる形に整えた開発記 | UNIX Cafe

Term-gotchi 第4回は、ここまで育ててきた小さなターミナルアプリを、git と GitHub で公開・管理できる形に整える編です。コード、README、CHANGELOG、インストール用スクリプト、ユーザーごとの状態ファイルを分けながら、「壊さず小さく育てる」やり方を Git の世界に持ち込んでいきます。
前回は、Term-gotchi の tg_talk を軽い英語教材として育てました。
Phrase、Theme、Tone、Meaning、Example を返せるようになり、相棒がただ話すだけではなく、英語表現の小さな練習相手になってきました。
ある程度アプリが形になってくると、次に気になるのは新しい機能を追加することよりも、この変更の積み重ねをどう残すかです。
別のマシンでも、このアプリを使えるようにしたい。そして、あとで修正したり機能を追加した時に、安全に更新できる形にしたい。
そこで今回は、Term-gotchi を手元のローカル環境にあるスクリプトから、Git で公開・管理できる小さなプロジェクトに育てていきます。
手元スクリプトのままだと、育てるほど不安になる
Term-gotchi は最初、かなり小さな zsh スクリプトとして始まりました。
状態を持ち、起動するたびに少し変化し、空腹や mood を見ながら反応する。最初はそれだけでも十分楽しかったのですが、第2回、第3回と進むうちに、だんだん手元のファイルだけでは管理しづらくなってきました。
- どのファイルが最新なのか分かりにくい
- 変更前の状態に戻しづらい
- 別の Mac に入れる手順が毎回あいまいになる
- README と実際のコマンドがずれやすい
- 公開したあと、更新方法を説明しにくい
小さいスクリプトでも、育て始めるとこういう問題はすぐに出てきます。
特に Term-gotchi は、育成アプリです。ユーザーごとの状態ファイルもあれば、相棒の履歴もあります。コードと個人の育成データが混ざると、公開もしづらいし、更新もしづらくなります。
そこで、スクリプトの管理にGit を使うことにしました。
この記事は Git のコマンドを覚えることが目的ではなく、育てた相棒を、壊さず残し、公開し、更新できる形にすることをテーマにします。
まずは、プロジェクトの形を整えた
GitHub に置く前に、最初にやったのはファイル構成の整理です。
手元で動いているだけなら、多少ファイルが散らばっていても何とかなりますが、git clone して使う人がいる前提で考えると、どこに何があるかが見える構成にしておきたいからです。
Term-gotchi では、だいたい次のような形を意識しました。
termgotchi/
bin/
tg
tg_talk
tg_history
install.sh
uninstall.sh
README.md
CHANGELOG.md
LICENSEポイントは、コード、説明、履歴、インストール処理を分けることです。
- 実行するコマンドは
bin/に集める - インストール処理は
install.shに寄せる - 削除の手順は
uninstall.shにまとめる - 使い方は
README.mdに書く - 変更の流れは
CHANGELOG.mdに残す
ここを整理すると、あとから自分が直すときにも、どこを見ればいいかがすぐに分かります。
また、誰かに試してもらうときにも、最初に読むべき場所が分かります。小さなアプリでも、ここを整えるだけでかなり扱いやすくなります。
Git で管理するものと、管理しないものを分ける
Term-gotchi を Git で管理するときに、一番気をつけたかったのはここです。
Git に入れるべきものと、入れてはいけないものを分ける。
普通のツールなら、ソースコード、README、設定例を入れればだいたい済みます。でも Term-gotchi は育成アプリなので、ユーザーごとの状態があります。
- 今の hunger
- 今の mood
- どの form まで成長したか
- どんな履歴が残っているか
- どのマシンで、どれくらい使われているか
こういうものは、公開するコードではなく、その人の環境に残るデータです。
なので Git で管理するのは、あくまでアプリ本体、説明、インストール手順、変更履歴にします。育成状態やログ、一時ファイルはリポジトリに入れません。
その境界を明確にするために、.gitignore も用意します。
*.log
.DS_Store
termgotchi_state
termgotchi_history
tmp/Git で公開する前提で考えると、共有すべきものと、個人の環境に残すものを分けることが大切になります。
ここを分けておくと、あとから git pull で更新しても、育てた相棒の状態を壊しにくくなります。
コミットは、プロジェクトの成長記録になる
第2回では、tg_history で相棒の成長を振り返れるようにしました。
Git のコミットログも、それに少し似ています。
tg_history が相棒の成長記録なら、git log はプロジェクトの成長記録です。
そこで、コミットメッセージも単なる作業メモではなく、あとから見て「何を育てたのか」が分かる形にしたいと思います。
例えば、こういうメッセージだと後から見た時に、修正の中身を追いづらくなります。
update
fix
色々変更
調整その時は覚えているのですが、数週間後に見返すと、具体的に何を変えたのかが分からなくなります。
Term-gotchi では、こういう粒度のほうが向いています。
Add tg_talk lesson metadata
Add evolution history command
Document install workflow
Ignore local state files
Add uninstall script大げさなルールは必要ありません。
ただ、ひとつのコミットにひとつの意味を持たせる。あとから見たときに、その変更が何のためだったか分かるようにする。
それだけでも、Git の履歴はかなり読みやすくなります。
README は、最初の体験を作る場所だった
GitHub で公開するなら、README.md はかなり重要です。
README は単なる説明書ではなく、初めて見た人が、「これは何で、どう試せばいいのか」を判断する場所です。
Term-gotchi の README では、最低限このあたりを書いておきたいと考えました。
- Term-gotchi が何をするアプリなのか
- どんなコマンドがあるのか
- どうインストールするのか
- どうアンインストールするのか
- 状態ファイルはどこに保存されるのか
- 英語学習 flavor として何ができるのか
特に第3回で育てた tg_talk は、README でもちゃんと説明したいところです。
単に「英語で話します」と書くだけだと内容が伝わらない。実際には、Phrase、Theme、Tone、Meaning、Example を返す micro lesson のような機能になっています。
なので README には、実際の出力例も載せます。
% tg_talk
Sounds good. What do you want to tackle next?
Phrase: deliberate step / thoughtful move
Theme: careful decision language
Tone: careful
Meaning: Good for pushing back against random experimentation in favor of one intentional step.
Example:
A: Do you want to try a bunch of small changes?
B: Not really. I think one thoughtful move is better.こういう例があると、初めて見る人も「これは何が楽しいのか」を掴みやすくなります。
install.sh で、試せる状態にする
GitHub にコードを置くだけでも公開はできます。
でも、それだけだと、実際に使い始めるまでに少しハードルが高くなります。
zsh スクリプトをどこに置くのか。実行権限はどうするのか。PATH は通っているのか。状態ファイルはどこに作るのか。
そこを毎回 README だけで説明するよりも、install.sh にまとめたほうが使いやすくなります。
このアプリを利用する側から見ると、こういう流れになります。
git clone https://github.com/k1117n-cmyk/termgotchi.git
cd termgotchi
./install.shインストール用スクリプトでやりたいことは、安全に管理ができるようにすることです。
- 必要なコマンドを配置する
- 実行権限を付ける
- PATH の確認や案内をする
- 既存ファイルをむやみに上書きしない
- 状態ファイルの置き場所を分かりやすくする
この部分も、最初の段階から同じ方針で続けています。
勝手に大きく環境を書き換えず、必要なところだけを小さく触る。
ターミナルアプリは、使う人の shell 環境の中に入っていくものです。だからこそ、インストール処理は慎重にしたいと思っています。
アンインストールできることも、配布の一部
小さな個人ツールだと、インストール手順だけを書いて終わりにすることもあると思います。
でも、配布するならアンインストールも、インストール以上に大事だと思うのです。
試してみたけれど合わなかった。別の場所に入れ直したい。状態ファイルを残したままコマンドだけ消したい。そういうことは普通にあります。
なので uninstall.sh も用意しておくと、利用する側の心理的な負担がかなり下がります。
./uninstall.shここで気をつけたいのは、何を消すかをはっきり分けることです。
- コマンドだけ消すのか
- 状態ファイルも消すのか
- 履歴も消すのか
- バックアップを残すのか
Term-gotchi の場合、状態ファイルはその人が育てた相棒そのものです。アプリ本体よりも、むしろそちらのほうが個人的なデータです。
だから、削除処理ではコードと状態を同じ扱いにしないほうが安全です。
更新は git pull で済むようにしたい
Git で配る一番の良さは、最初の配布よりも、その後の更新にあります。
zip ファイルで配ることもできます。小さなスクリプトなら、それでも十分な場面はあります。
でも、あとから機能を足したり、不具合を直したり、README を更新したりするなら、git pull で追い続けるほうが後々楽になります。
cd termgotchi
git pull
./install.shこの流れにしておけば、リポジトリ側のコードを更新してから、必要に応じてインストール済みコマンドを入れ直せます。
ここでも大事なのは、ユーザーの状態ファイルを壊さないことです。
コードは Git で更新する。状態はユーザーの環境に残す。CHANGELOG を見れば、何が変わったか分かる。
この分担ができていると、Term-gotchi はかなり更新しやすくなります。
CHANGELOG.md は、読むための履歴にする
Git の履歴があれば、変更内容はすべて残ります。
それでも CHANGELOG.md を書く意味はあります。
git log は開発者向けの細かい履歴です。一方で CHANGELOG.md は、使う人に向けた読みやすい履歴です。
例えば、コミットログには細かくこう残っていたとしても、
Add lesson metadata fields
Add tone labels
Add two-line examples
Fix tg_talk output spacingCHANGELOG では、もう少し使う人目線にまとめられます。
## 0.3.0
- Expanded tg_talk into a small English-learning mode.
- Added Phrase, Theme, Tone, Meaning, and Example fields.
- Improved output readability for short terminal sessions.細かい作業の履歴と、使う人に伝える変更点は、似ているようで少し違います。
この 2 つを分けておくと、自分も後から振り返りやすいし、使う人にも何が変わったか伝わりやすくなります。
GitHub に置くと、プロジェクトの見え方が変わる
GitHub に置いたからといって、急に大きなソフトウェアになるわけではありません。
Term-gotchi はあくまで、zsh で動く小さなターミナルアプリです。
でも、GitHub に置く前提で整えると、見え方はかなり変わってきます。
- README を読めば何をするものか分かる
install.shで試せるuninstall.shで戻せるCHANGELOG.mdで変更を追えるgit pullで更新できる
こうなると、手元の思いつきスクリプトではなく、小さくても「配れるソフトウェア」になります。
そして不思議なことに、自分用のツールでも、公開できる形に整えようとすると設計が少し丁寧になります。
どこまで自動でやるか。どこからはユーザーに確認するか。状態ファイルをどう守るか。README に何を書けば初回体験が伝わるか。
GitHub に置くというより、誰かが触れるかもしれない形にすることで、プロジェクトの輪郭がはっきりしてくる感じがあります。
今回の変更で、Term-gotchi は配れる形に近づいた
第4回でやったことをまとめると、こうなります。
- Term-gotchi を Git / GitHub で管理できる形にした
- コードとユーザーごとの状態ファイルを分けた
README.mdで最初の体験を説明できるようにしたCHANGELOG.mdで変更の流れを読めるようにしたinstall.shとuninstall.shで試しやすく戻しやすい形にしたgit pullで更新できる土台を作った
育成アプリとしての成長記録は tg_history に残る。
プロジェクトとしての成長記録は Git に残る。
この 2 つが揃うと、Term-gotchi はかなり面白いものになります。
相棒は shell の中で育ち、コードは Git の履歴として育つ。小さな zsh アプリでも、ちゃんと「育っていくソフトウェア」になってきました。
次は、更新体験そのものを育てたい
今回で、Term-gotchi は GitHub から clone して試せる形になりました。
ただ、まだ改善できるところはあります。
tg_updateのような更新用コマンドを作る- バージョン番号を表示できるようにする
- release tag を切って更新点を見やすくする
- Homebrew など、もう少し自然な配布方法を考える
- インストール時に既存環境をもっと丁寧に検査する
つまり、公開する形はできたので、次は更新する体験をどう気持ちよくするかです。
Term-gotchi は、第1回では zsh の中で動く小さな相棒でした。第2回で成長履歴を持ち、第3回で英語の micro lesson を話し、第4回で GitHub に公開できる形になりました。
手元の小さな遊びが、少しずつソフトウェアらしくなっていく。その過程そのものが、今回の記事の一番面白いところだった気がします。
Term-gotchi を GitHub で育てています
Term-gotchi のソースコードは GitHub で公開しています。インストール用スクリプトや配布パッケージ作成用のスクリプトも含めて置いているので、zsh 製の小さなターミナルアプリを作るときの参考にもなると思います。
最初から読みたい方へ
今回は、Term-gotchi を Git と GitHub で公開・管理できる形に整えました。
その出発点となる第1回では、zsh の中で育つ小さな相棒アプリとして、Term-gotchi を最初に動かすところまでを紹介しています。安全なシェル設計、.zshrc への追加方法、状態ファイルの扱いなど、今回の Git 管理の土台になる部分です。
👉 第1回「ターミナルで育つ相棒を作ろう。zsh製ミニ育成アプリ『Term-gotchi』開発記」へ戻る








