dowel

ADR-0013: dowel 自体の取得は別バイナリが担い、参照は commit sha に固定する

状態: 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 のような日次アーカイブを持たないため、 日付は履歴への問い合わせで解決する
  • 取得には Rust ツールチェーンを要する。prebuilt バイナリの配布と その検証は未決事項とする(Q10)
  • .dowel-version に手書きでチャネル名を書いた場合、shim は解決せずに 誤りとして拒む。暗黙にネットワークへ触れないための制約であり、 dowelup pin <指定子> が解決して書き直す
  • ネットワークに触れるのは install / pin / default のみ