状態: 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節の
「Path を Str と別型にするのは、文字列連結によるパス構築を言語として
提供しないためである」という方針と衝突するためである。
プレースホルダはパスの構築を文字列操作として導入する。transfer の中でのみ
許可する形も取れるが、その場合、文字列補間が使用できる箇所とできない箇所を
利用者が把握する必要が生じる。パス構築を言語が扱わないという方針は
規則の総量を減らすためのものであり、例外はその目的に反する。
案 C を採らない理由は、想定していない転送手段が書けなくなるためである。 adb push、独自のブートローダ、ネットワーク経由の書き込みなど、 組込み用途で実際に使われる手段は多岐にわたる。種別を閉じると、 実装が種別を追加するまで利用者は待つことになる。
host を args にも重ねて書くことになる(上の例では board.local が2箇所)。
これは案 A が引数の途中に値を埋められないことの直接の結果であるtransfer と remote_dir は同時に指定する。片方だけの場合は
incomplete-runner で拒む。片方では転送先が決まらないか、
転送先だけあって運ぶ手段が無い状態になる将来、案 B が必要になった場合はこの ADR を Superseded とし、 文字列補間を言語に導入する判断を別の ADR として記録する。