dowel

ADR-0008: ランナーの転送先パスは位置で決め、文字列補間を導入しない

状態: Accepted

文脈

SSH や シリアル経由のランナー(30-devexp.md 1節)は、 対象機がビルド機のファイルシステムを参照できないため、起動の前に成果物を 転送する必要がある。転送コマンドには「転送元のローカルパス」と 「転送先のパス」の2つを渡さなければならない。

このパスをマニフェストにどう書かせるかで、以下の選択肢があった。

記法
A. 位置で決める transfer = ["scp", "-q"] と書き、末尾に2つのパスを実装が付す
B. 文字列補間 transfer = ["scp", "{binary}", "board:{remote}"]
C. 種別を閉じた語彙にする kind = "ssh" とし、転送手順は実装が持つ

案 B は表現力が最も高い。scp の host:path のように引数の途中へ値を置く形も、 rsync・adb push・独自の書き込みツールも、語彙を追加せずに記述できる。

決定

案 A を採る。転送コマンドの末尾に <ローカルパス> <転送先> を、 起動コマンドの末尾に <転送先のパス> を、実装が付け足す。 マニフェストにプレースホルダは現れない。

host:path の形が必要な場合のために host プロパティを設ける。 host が設定されている場合、転送先は <host>:<remote_dir>/<成果物名> になる。

[runner.aarch64-unknown-linux-gnu]
host       = "board.local"
remote_dir = "/tmp/dowel"
transfer   = ["scp", "-q"]
command    = "ssh"
args       = ["board.local"]

上記は以下の2つのコマンドに展開される。

scp -q <build>/bin/unit_test board.local:/tmp/dowel/unit_test
ssh board.local /tmp/dowel/unit_test

根拠

案 B を採らない理由は、10-manifest.md 3節の 「PathStr と別型にするのは、文字列連結によるパス構築を言語として 提供しないためである」という方針と衝突するためである。

プレースホルダはパスの構築を文字列操作として導入する。transfer の中でのみ 許可する形も取れるが、その場合、文字列補間が使用できる箇所とできない箇所を 利用者が把握する必要が生じる。パス構築を言語が扱わないという方針は 規則の総量を減らすためのものであり、例外はその目的に反する。

案 C を採らない理由は、想定していない転送手段が書けなくなるためである。 adb push、独自のブートローダ、ネットワーク経由の書き込みなど、 組込み用途で実際に使われる手段は多岐にわたる。種別を閉じると、 実装が種別を追加するまで利用者は待つことになる。

帰結

将来、案 B が必要になった場合はこの ADR を Superseded とし、 文字列補間を言語に導入する判断を別の ADR として記録する。