状態: Accepted
dowel を使うプロジェクトが、使用する dowel の版を宣言し、環境に依らず 同じ版でビルドできる必要がある。rustup が確立した使用感(stable / nightly、 任意の版の指定、プロジェクト単位の固定、透過的な切り替え)に加えて、 リリースが未整備である現状では、上流の特定の branch / commit を 直接使えることが要る。
決める点は3つあった。
| 論点 | 選択肢 |
|---|---|
| 機構の置き場所 | A. 本体に内蔵(dowel self install) / B. 別バイナリ / C. ブートストラップスクリプトのみ |
| 取得の手段 | git / cargo の起動に委譲する / HTTP クライアント等の crate を導入する |
| 固定として記録するもの | commit sha / チャネル名やブランチ名のまま |
前提となる規約: 「外部の成果物はすべて一意に固定する。タグやブランチ名のみに よる参照は固定とみなさない」(50-development.md 5節)。
案 B を採る。取得・固定・切り替えは別バイナリ dowelup(crates/dowel-up)が担う。
git(clone / fetch / 参照の解決)と
cargo(ビルド)の起動に委譲する。dowelup 自身も外部 crate に依存しない
(ADR-0007)stable / nightly / nightly-<日付> / X.Y.Z /
branch:<名前> / tag:<名前> / sha)は、install / pin / default の
時点で commit sha に解決され、以後は sha が正本になる。
インストール先は $DOWELUP_HOME/versions/<sha>/.dowel-version に書く。書かれるのは解決済みの
sha であり、チャネル名やブランチ名は書かないdowel という名前で起動された dowelup(シンボリックリンク)は shim として
働き、.dowel-version → 既定、の順で版を選んで exec する。
この経路はネットワークに触れない別バイナリにする理由。 更新機構が更新対象の中にあると、壊れた版を 掴んだときに脱出手段も一緒に壊れる。また、実行中の自分自身を置き換える 処理は固有の問題(実行中バイナリの上書き、途中失敗時の状態)を持ち込み、 起動時間の予算(20-architecture.md 5.4)を持つ 本体の起動経路に分岐を足すことになる。rustup / rustc の分離と同じ判断である。
案 C を採らないのは、1回きりの取得しかできないためである。プロジェクト単位の pin と透過的な切り替えは、起動のたびに版を選ぶ常設の入口を要する。
外部コマンドへ委譲する理由。 ソース取得に必要なプロトコル(HTTPS、SSH、 git プロトコル)を自前実装するか crate を導入するかの二択を避けられる。 実行層を ninja に委ねた判断(00-overview.md 7節)と 同じく、確立したツールの責務は奪わない。
sha に固定する理由。 タグとブランチは可動であり、規約上も固定と みなさない。sha を正本にすると、(1) 同じ pin からは常に同じ内容が得られ、 (2) shim の選択がネットワークに触れずに決定でき、(3) 将来 prebuilt 配布 (Q10)を足しても pin の形式が変わらない。
dowelup の名は仮称 dowel に追随する(ADR-0006)。
名称の確定時に一緒に改名するstable と X.Y.Z は、上流に release タグが現れるまで解決できない。
それまでは nightly / branch / sha を使うnightly-<日付> は「既定ブランチに、その日(UTC)の終わりまでに入った
最後のコミット」と定義する。rustup のような日次アーカイブを持たないため、
日付は履歴への問い合わせで解決する.dowel-version に手書きでチャネル名を書いた場合、shim は解決せずに
誤りとして拒む。暗黙にネットワークへ触れないための制約であり、
dowelup pin <指定子> が解決して書き直すinstall / pin / default のみ