rigor-hanami
Hanami 3.xアプリに対してHanami::Actionプロトコルを強制します。app/actions/**/*.rb配下のすべてのクラスは#handle(request, response)を定義しなければならず(MUST)、それらの本体の内部でRigorは2つのパラメータをそれぞれHanami::Action::Request / Hanami::Action::Responseとして型付けするため、誤用が的確に捕捉されます。これはADR-28のパススコープのメソッドプロトコル契約(contract)のリファレンス実装としてのプロダクション利用者です ── Rigorがパラメータ型を提供し、プラグインがメソッドのシェイプ(shape)を検査します。ソースのみを読み取り、hanamiランタイム依存を持ちません(Request / Response / Paramsのサーフェス(surface)に対するRBSスタブを同梱しています)。
これはrigortypeにバンドルされて配布されます。plugins:の下で有効化します。
plugins: - rigor-hanamiWhat it checks
Section titled “What it checks”module Bookshelf module Actions module Books class Index < Bookshelf::Action def handle(request, response) response.status = 200 # response: Hanami::Action::Response response.body = request.params[:q] # request: Hanami::Action::Request request.no_such_method # エラー: call.undefined-method end end end endend| ルール | 重大度 | 発火条件 |
|---|---|---|
plugin.hanami.missing-handle-method | error | マッチするファイル内のクラスが#handleを定義していない |
plugin.hanami.handle-arity-mismatch | error | #handleが2以外のパラメータ数で定義されている |
適合する#handleの内部では、request / responseの誤用はエンジン自身のcall.undefined-methodとして顕在化します ── 型がRBSで宣言されていた場合とまったく同じです。戻り値型の適合性は検査されません。#handleは契約上voidであり(responseはインプレースで変更される)、戻り値を検査するとあらゆる条件分岐で偽陽性が発生してしまうためです。パラメータ名は任意です(バインドされるのは名前ではなく位置です)。検査されるのは直接定義された#handleのみで、継承されたものは対象外です。
plugins: - gem: rigor-hanami config: action_path: "app/actions/**/*.rb" # デフォルトカスタムなスライス(slice)レイアウトのためにaction_pathを上書きできます(例: "slices/main/actions/**/*.rb")。この上書きは、パラメータ型の提供と#handleの検査の両方を再ターゲットします。
- 厳密なアリティ(arity)。
#handleはちょうど2つのパラメータを取らなければなりません。オプショナルまたはキーワード専用の形式はhandle-arity-mismatchとしてフラグされます。 - 直接定義のみ。基底クラスから継承された
#handle(クラス自身で定義されたものではない)は検出されません。 - スタブ化されたサーフェス。バンドルされたRBSはドキュメント化されたRequest / Response / Paramsのメソッドをカバーします。そのサーフェス外への呼び出しは、稼働中のHanamiインストールではなくスタブに対して解決されます。
プラグインの内部
Section titled “プラグインの内部”ProtocolContract宣言、アクションチェッカー、RBSスタブ、ADR-28のprovide-and-check分割については、プラグインのREADMEにあります。プラグインの書き方についてはexamples/とrigor-plugin-authorスキルを参照してください。
© 2026 TypedDuck. Licensed under CC BY-SA 4.0.