ERBテンプレートのtrim_mode対応により設定ファイルの空行制御が可能に
Kamalの設定ファイル読み込み処理が拡張され、ERBテンプレートの trim_mode: "-" が有効化されました。これにより、条件分岐を含む設定ファイルで不要な空行が挿入される問題が解消されます。
背景
Kamalの設定ファイル(deploy.ymlやdeploy.staging.ymlなど)はERBテンプレートとして処理されますが、従来は条件分岐を含むテンプレートで意図しない空行が残る問題がありました。例えば、環境変数の有無で動的にサーバーリストを構築する際、<% if ... %>ブロックが空行を残してしまい、YAMLの構造が崩れることがありました。
以下の例では、ENV['EXTRA_IP']が存在する場合にサーバーを追加しますが、従来の実装では条件ブロックが2行の空行を残していました:
servers:
- 1.1.1.1
- 1.1.1.2
この空行はYAMLパーサーには影響しませんが、設定の可読性を損ない、意図しない構造変化を招く可能性がありました。
技術的な変更
lib/kamal/configuration.rbのload_config_fileメソッドが変更され、ERBテンプレートの初期化時にtrim_mode: "-"オプションが追加されました。
変更前:
YAML.send(load_method, ERB.new(File.read(file)).result).symbolize_keys
変更後:
template = File.read(file)
rendered = ERB.new(template, trim_mode: "-").result
YAML.send(load_method, rendered).symbolize_keys
この変更により、テンプレート内で-%>を使用した場合、その行の改行が削除されるようになります。以下のテンプレートは、条件分岐による空行を残しません:
service: app
servers:
- <%= ENV['MAIN_IP'] %>
<% if ENV['EXTRA_IP'].presence -%>
- <%= ENV['EXTRA_IP'] %>
<% end -%>
レンダリング後の結果は以下のようになり、サーバーリストが連続した行として出力されます:
servers:
- 1.1.1.1
- 1.1.1.2
test/cli/main_test.rbには、このtrim_mode動作を検証する2つのテストケースが追加されました。1つ目は基本設定ファイルでの空行削除を検証し、2つ目はdestination固有の設定ファイル(deploy.staging.ymlなど)でも同様に機能することを確認しています。
設計判断
ERBのtrim_modeオプションを利用する方式が採用されました。独自の空行削除処理を実装するのではなく、ERBの標準機能を活用することで、Rubyエコシステムとの一貫性を保っています。
trim_modeには複数のオプション("%", "<>", ">", "-")が存在しますが、"-"が選択されました。このモードでは、-%>を使用した行の末尾の改行のみを削除し、<%や<%=の動作には影響しません。テンプレート作成者が明示的に-%>を記述した箇所のみで空行削除が有効化されるため、既存のテンプレートへの影響を最小限に抑えられます。
変更前のERB初期化が1行で完結していたのに対し、変更後は3行に分割されています。これはテンプレートの読み込み、レンダリング、YAMLパースの各ステップを明確に分離し、将来的なデバッグやエラーハンドリングの拡張を容易にする意図があると考えられます。
まとめ
本PRは、KamalのERBテンプレート処理にtrim_modeを追加し、条件分岐による空行制御を可能にした変更です。標準的なERB機能の活用により、既存のテンプレートとの互換性を維持しながら、設定ファイルの可読性向上と構造の安定化を実現しています。