SATySFiの最強のビルドツールを作りたい

はじめに

バージョンが異なるパッケージを共存して使うための、SATySFiのビルドツールの設計方法のアイデアです。

2022/10/24加筆:改めて考えを整理したのと、v0.1.z でのパッケージシステムの処理に関する設計という記事が公開され、新しいパッケージシステムの実装が進んでいることを受け、記事内容を色々と追記変更しました。

課題に感じていること

現状のSATySFiでは複数のパッケージが一つのパッケージの別のバージョンに対してそれぞれ依存していた場合、それらを解決する方法が存在しない。

(2022/10/24追記)

これは「一つの文書で」という話だけではなく、opamを通じてインストールしている環境全体の話でもある。

具体的な例としては、enumitemが2.0.0と3.0.0で非互換であり、3.0.0に依存しているパッケージと2.0.0に依存しているパッケージを同時に使うことができなくなっている。 これの影響により、satyrographos-repoで提供されているsatysfi v0.0.6に対応したパッケージのスナップショットがsnapshot-stable-0-0-6snapshot-stable-0-0-6--1の2つ別れてしまっている。

これは現在は解消されているものの、今後似たような事例が発生することは十分にあり得る。

イデアのコア

(2022/10/24追記・修正)

「文書ごとに依存解決を行う」という方法で上記の課題を解決する。

具体的には、

  • 文書のトップライブラリにユーザーが作成した文書の設定ファイルを元に依存解決を行う
  • 文書ごとに環境を作成し、その環境をもとにコンパイルを行う

という方法である。設定ファイルを作成する点は「v0.1.z でのパッケージシステムの処理に関する設計」でも想定されている手法であるが、「文書ごとに環境を作成する」という点が少し違う点である。

これにより、

  • SATySFi自体のバージョンを文書ごとに使い分けることができる
  • lockファイルを生成し、環境ごと保存することで、文書のビルド再現性を保証する事ができる

という効果を得ることができ、SATySFi本体に次々と新しい機能を入れたり、パッケージが新しく追加された機能を使った実装をしたりすることがこれ以上に可能となるという嬉しいことがある。

ユーザーが作成する設定ファイルは「SATySFi v0.1.0開発進展の現状報告」や「v0.1.z でのパッケージシステムの処理に関する設計」で触れられている設定ファイルと同じものになることを想定している。

同一文書内でのバージョンの矛盾の解消方法について

「文書ごとに環境を用意する」というアイデアは、一つの文書が依存するパッケージにバージョン衝突が発生してしまった場合にはそれだけでは解消することができない。

これを解決するために、ダーティーハックではあるものの、

  • 文書ごとに用意される環境内で、バージョンが違う同じパッケージが違う名前で保存されるようにする
  • 依存しているパッケージに書かれた呼び出し文を書き換える

という方法を考えている。

この方法は、SATySFi v0.0.xでは束縛列の上書きが発生してしまい、文書結果を想定ではないものに変えてしまう可能性が指摘されている。

しかし、SATySFi v0.1.xではそれが起きない設計になるため(v0.1.z でのパッケージシステムの処理に関する設計#全体処理)、問題ないと考える。

使用するSATySFiのバージョン情報を設定ファイルから得られるため、satysfi v0.1.x以上であれば複数バージョンの共存を有効化しsatysfi v0.0.xであれば無効化するなどの機能を実装することは容易である。

もちろんSATySFiの仕組みで上手く吸収出来れば(パッケージでの外部ライブラリ呼び出し時点でバージョン情報を指定する、など)それに越したことは無いため、自分の中での実装優先度は低いと考えている。

発展

生成したバージョン依存関係をlockファイルに書き出すことで、文書の生成再現性を保証することができるようになる。

また、グローバルな環境を汚染しないため、「ローカルフォルダ内の自作パッケージの使用」や「リリースされていない、開発中のパッケージのgitリポジトリの特定commit版の使用」といったことも可能になる(設定ファイルの書き方に工夫はいるかもしれないが)。

課題としては、キャッシュ戦略である。特に、文書に使われている画像などは変更が無い限りコピーしたくないため、その判定をどうするかを考える必要がある。

おわりに

実際に実装をしてみて、上手くいきそうであればsatyrographosにプルリクエストを送ってみたいと考えている。