← ishizakahiroshi.com
ツール紹介 2026-09-12

「解析できなかった」を「何も無い」に見せない。静的コード索引 omitnix を出しました

古い木製のカード目録棚。ほとんどの引き出しには索引カードが並び、いくつかの空いた枠には琥珀色の紙の札が下がっているヘッダー画像

図書館で蔵書の一覧を作るとします。ほとんどの本は題名を書き写せますが、何冊かは表紙が擦り切れて読めません。ここで読めなかった本を一覧から外すと決めた瞬間、その一覧は静かに嘘になります。読んだ人には「そんな本は無い」と見えるからです。コードの一覧を作る道具も、たいていこれをやっています。

Qiita で読む(技術版)→ note で読む(一般向け)→ omitnix リポジトリ →
omitnix でできることをまとめた要約図

生成物は JSON が 1 つ。Python 3.11 以上だけで動きます。

落ちたファイルは、出力に出ない

静的解析でコードの目録を作ること自体は、そう難しくありません。難しいのは、その目録が「全量である」と言い切れる状態を保つことです。よくある生成器はパーサが解釈できないファイルを黙って飛ばすので、出てくるのは「読めた範囲の目録」なのに、読み手にはそれが「全量の目録」と区別できません。

omitnix はこれを成果物の側で解いています。走査で発見した数と、解析できた数・一部を追えなかった数・読もうとして読めなかった数・担当するアダプタが無い数の合計が一致しなければ、その実行を失敗させます。

発見した数が 4 つの区分に分かれ、合計が一致しなければ実行が落ちることを示した図

読めなかったファイルは結果から消えず、名前と理由が残ります。

「担当がいない」と「担当すると言ったのに読めなかった」は別物として数えます。前者は拡張子ごとの件数、後者は 1 件ずつの名指しで、実行を落とすのは後者だけです。同じ「0 件」でも、調べた結果の 0 件なのか、そもそも調べていない 0 件なのかが区別できます。

出した翌日に、自分の道具に裏切られた

v0.1.2 で「どこに入れたか、古くなっていないか」を調べる機能を足しました。公開した直後に素の環境へ入れて動かしたら、索引を持つ 9 つのリポジトリを全部「古い」と報告し、作り直しを勧めてきました。

パーサが入っていない環境だったので、その実行は元のファイルを読めていません。読めない実行の結果と、読めた実行が残した索引を比べて、違うから古い、と言っていたわけです。自分が置き換えようとしていた間違いを、自分でやっていたことになります。

「古い」と「この環境では確認できなかった」を別の状態として扱うようにした変更を示した図

比べられる装備があるかを先に問い、無ければ unverified として報告します。足りないものは 1 つのコマンドにまとめて名指しします。

CI はすべて緑で、publish も成功し、バージョン番号も一致していました。それでも見つからなかったのは、どのゲートも依存が揃った環境で走っていたからです。この 1 件から、配ったものを素の環境で 1 回動かすまでをリリースの手順に足しました。

記事に書いたこと

Qiita 版には、完全性の不変条件の実装、unknown と unclaimed を分ける理由、5 つの項目状態の設計、v0.1.3 で足した unverified の判定ロジックと、それを裏付けるテストの書き方を入れています。note 版は同じ出来事を、道具を使う側から見た話として書きました。

使い方は omitnix の使い方ページ に、機能の一覧とスクリーンショットは 作品ページ にまとめてあります。