検索/コード例を全部テストする解説書を、書き足して直していく

コード例を全部テストする解説書を、書き足して直していく

載せたコード例を全部テストする解説書を直す時に使う。作る・テストするコマンド、例の2つの置き方、共通のライブラリのバージョンを上げずに例を別のフォルダへ移す方法、レビューの前のチェックリストを示す。

このAIルールを使うには
## 解説書のコード部分を、テストされるコードとして扱う この書籍は、コードブロックを埋め込んだマークダウンファイルとして書かれた実践的な例の集まりである。ドキュメントテスト用のハーネスがソースツリーを走査し、すべてのコードブロックを抽出してコンパイルし、実行する。そのため、壊れた例はアプリケーションコードが壊れた場合とまったく同じようにビルドを失敗させる。 ### すべての編集にとってそれが意味すること コンパイルできない例はドキュメントではない。散文は自由に書き直してよいが、コードブロック内部の変更はテスト対象ソースへの変更であり、提案する前に必ずテストコマンドを通さなければならない。 ### レンダリングされた書籍とテスト対象面を同期させ続ける 同じマークダウンがレンダリング後の書籍とテストハーネスの両方に供給されるため、書式上の選択が意味を持つ。コードブロックに付けた注釈はハーネスがそのブロックをどう扱うかを決め、読者から隠された行も依然としてコンパイルされる。レンダリングされたページの見た目を整えるためだけに、注釈や隠し行を取り除いてはならない。 ## 決められたコマンドで、解説書を作り、テストし、画面で確かめる その場しのぎの呼び出しを考え出すのではなく、日常的な操作はすべてドキュメント化されたコマンド経由で行う。そうすればローカルでの実行が継続的インテグレーションと一致する。 ### 重要なコマンド - マークダウンのソースから書籍をビルドする。 - ドキュメントテストとスペルチェックの通過を合わせた、スイート全体を実行する。 - コードブロックを変更して高速なループを回したいときは、ドキュメントテストのターゲットだけを実行する。 - 散文の編集中はライブリロード付きでローカルに書籍を配信する。 - レビュー前の既定として、ビルドとテストをまとめて実行する。 - リンクチェッカーを実行する。これはチェックインされた設定ファイルに照らして内部リンクと外部リンクを検証する。 - スペルチェックのスクリプトを対話的に実行し、正当な新語はリポジトリの辞書ファイルに追加する。そうすればその追加が変更と一緒にレビューされる。 ### ツールチェーンを固定する 書籍ジェネレーターとリンクチェッカーは、ドキュメント化された単一のインストールコマンドから、正確に固定されたバージョンでインストールされる。失敗を回避するためにローカルでツールをアップグレードしてはならない。バージョンのずれは、再現可能な失敗を自分だけにしか見えない失敗へ変えてしまうからである。 ## 例の2つの置き方を知り、共通のライブラリのバージョンは上げない 例は2つの方法のいずれかでテストされる。あるファイルがどちらのパターンを使っているかを知ることで、そのコードと依存関係がどこに置かれるかが決まる。 ### パターン1: その場でテストされるインラインのブロック コードブロックはソースツリー配下のマークダウンに直接置かれる。ビルドスクリプトがそのツリーからマークダウンファイルを探し、コードブロックごとに1つのテストを生成する。そうした例が必要とする依存関係は、すべてルートのマニフェストにあらかじめ存在していなければならない。ブロックには言語のエディションを指定する注釈と、コンパイルのみ・パニックを期待・スキップといった挙動を指定する注釈を付けられる。読者に不要な定型コードは、ハッシュ記号とスペースを先頭に付けた行として書く。ハーネスはそれをコンパイルするが、レンダリングされた書籍では非表示になる。これはレガシーなパターンで、動作は維持するが拡張はしない。 ### パターン2: マークダウンへ取り込まれる独立パッケージ コードは共有のコードディレクトリ配下にある独立したマニフェストを持つ自分のパッケージに置かれ、マークダウンは相対パスでソースファイルを指すインクルードディレクティブによってそれを取り込む。行範囲指定のインクルードを使えばページにファイルの一部だけを表示でき、これによりテスト用の足場がレンダリングされる例から除かれる。そのパスはビルドスクリプト内でドキュメントテストのハーネスから除外され、コードが二重にテストされないようにする。これが新規および移行済みの例で推奨されるパターンである。 ### 依存関係のルール ルートのマニフェストで依存関係のバージョンを変更してはならない。ルートのマニフェストはすべてのインライン例で共有されているため、あるページのためのバージョン引き上げが、他の数十の例を気づかないうちに壊しかねない。ある例により新しい依存関係が必要になった場合は、代わりにその例を独自の固定バージョンを持つ独立パッケージへ移行する。 ## 新しいライブラリが要る例は、専用のフォルダへ移す 依存関係のバージョンを変える必要が生じたら、影響を受ける例を独立パッケージへ変換する。各手順は次の手順が前提とする状態をリポジトリに残すため、順番どおりに進めること。 1. 共有のコードディレクトリ配下に、カテゴリー名、次に例の名前を付けたフォルダとして、独自のマニフェストを持つパッケージを作成する。可能な場合は共有の依存関係をワークスペースから継承し、逸脱させること自体が目的である場合は独立してバージョンを固定する。 2. コードをマークダウンのコードブロックからパッケージのソースへ移す。実行可能な例ごとに1つのバイナリ、ライブラリ形式の例ならライブラリモジュールとする。 3. そのパッケージをルートのマニフェストにあるワークスペースのメンバー一覧へ登録する。 4. マークダウン内のインラインコードを、マークダウンファイル自身の位置からパッケージのソースまでの相対パスを持つインクルードディレクティブへ置き換える。 5. 移行したパスをビルドスクリプト内でドキュメントテストのハーネスから除外する。除外リストは2つある。ディレクトリの接頭辞を受け取ってその配下すべてを対象から外すものと、単一のマークダウンファイルを受け取るものである。当てはまるうち、より範囲の狭い方を使う。 6. 両側をテストする。新しいパッケージ自身のテストを実行し、さらにドキュメントテストのターゲットを再実行して、ブロックを取り除いたことで残りのインライン例が壊れていないことを確認する。 手順5の前で止まった移行は、その例を二重にコンパイルされたまま残す。手順6の前で止まった移行は、気づかないうちにカバレッジを落としかねない。 ## 何を作り、何をテストするかを決めているファイルを読む ごく少数のファイルが、何がテストされ、何がレンダリングされ、どんなコマンドが存在するかを決めている。挙動を変える前にそれらを読み、意図をもって変更すること。 - ルートのマニフェストは、インライン例が使う依存関係とワークスペースのメンバー一覧を保持する。 - ビルドスクリプトは、ドキュメントテストのハーネス向けにマークダウンを検出し、移行済みの例が二重にテストされないようにする2つの除外リストを持つ。 - 書籍の設定ファイルは、マークダウンがどのように書籍へレンダリングされるかを制御する。 - ビルドツールの設定は、ドキュメント化されたコマンドが依存しているタスクランナーのエイリアスを定義する。 - タスクランナーのパッケージは、ビルド・テスト・リンクチェックをサブコマンドとして実装しており、同じロジックが貢献者と継続的インテグレーションの両方に使われる。 あるコマンドの挙動がここでの説明と異なる場合は、上記のファイルを正本として扱い、回避策で済ませるのではなく説明の方を直すこと。 ## 読者がコピーしてそのまま動かせる、完全な例を書く 例の良し悪しは、誰かが自分のプロジェクトへコピーして動かせるかどうかで判断される。ページ上でどれだけ短く見えるかではない。 ### 内容のルール - 例は断片ではなく、完全でコンパイル可能なものにする。 - 失敗時にパニックさせるのではなく、その言語のエラー伝播演算子でエラーを伝播させ、プロジェクトが定めたエラー処理のパターンに従う。 - グロブインポートを避け、その例がどのトレイトや要素に依存しているかを読者が正確に見て取れるようにする。 - 外部サービスやネットワークアクセスを必要とする例はコンパイルのみと印を付け、スイートがオフラインでも実行可能な状態を保つ。 - 定型コードは取り扱いを終えるのではなく隠し行の接頭辞で隠し、例がコンパイルできる状態を保つ。 - 新しい例では、ルートのマニフェストに依存関係を追加するより、独立パッケージを作ることを優先する。 ### 新しい最上位セクションを追加する場合 最上位のセクションページを新しく追加したときは、書籍の目次ページにもそれへのインクルードを、アルファベット順の正しい位置に追加すること。目次ページは読者の入口であり、そこに含まれていないセクションは、ビルドが成功していても事実上見えないままになる。 ## レビューを頼む前に、全部のテストとチェックリストを通す レビュー用に変更を出す、または更新する前に以下すべてを検証し、書き直しを行ったあとにも再度検証すること。 - テストスイート全体がローカルで通っていること。部分的な実行ではなく、ドキュメント化された全テストのコマンドを使う。 - コミットが1つにまとめられ、最新のmainブランチへリベースされていること。 - 説明に正しい課題クローズ節が含まれていること。対応する課題が存在しない場合は、その節を完全に取り除く。誤った課題番号は、無いことよりも悪い。 - レンダリングされない一覧が並び順どおりであること。リンク、参照、識別子、マニフェストの記載が対象。並び順を保つことが、将来の差分を小さく保つ。 - 外部APIリファレンスページへのドキュメントのリンクは、固定バージョンではなくワイルドカードのバージョン部分を使うこと。そうすれば次のリリースでリンクが腐らない。 - 例がプロジェクト標準のエラー処理を使っていて、失敗時にパニックさせる近道を取っていないこと。 - 説明内のコード識別子がバッククォート付きの名前で書かれ、ファイル末尾のリンク定義を通じてそのリファレンスページへハイパーリンクされていること。 提出後は継続的インテグレーションの実行を見守り、報告された失敗はその場で直すこと。赤いままの変更をレビュアーの仕分けに委ねて放置しない。