Контракт шаблонов¶
Крейт поставляет шаблон для cargo generate.
Шаблон проверяется в CI того же крейта, поэтому заготовка не расходится с его API.
Форма¶
Шаблон - это каталог, по которому cargo generate создаёт заготовку:
templates/<name>/
├── cargo-generate.toml # манифест: описание, объявленные плейсхолдеры
├── Cargo.toml.liquid # name = "{{project-name}}"; пины ruststream + крейта брокера
└── src/
├── main.rs # билдер #[ruststream::app]
├── orders.rs # обработчики #[subscriber]
└── routes.rs # Router, собирающий обработчики
- Плейсхолдеры записываются на Liquid-синтаксисе cargo-generate. Плейсхолдер
{{project-name}}встроен и принимает значение--name, поэтому минимальный шаблон не объявляет своих. - Манифест пакета называется
Cargo.toml.liquid. При генерации cargo-generate убирает суффикс.liquid. Суффикс здесь не украшение: при поиске пакетов в git-источнике cargo разбирает каждыйCargo.tomlрепозитория и не смотрит наexclude. Из-за плейсхолдера в имени пакета cargo отвергает манифест, и эту ошибку видит любой, кто зависит от крейта по git-источнику. Так же называйте и любой другой шаблонный файл, который стал бы разбирать cargo. - Манифест пакета закрепляет
ruststreamна поддерживаемой минорной версии, а крейт брокера - на его собственной. - Один шаблон на транспорт или топологию брокера: например,
natsиnats-jsилиredis-stream,redis-pubsub,redis-list.
Исходники шаблона содержат плейсхолдеры {{...}} и до генерации не проходят разбор ни как Rust, ни
как TOML. Держите их вне рабочего пространства cargo: exclude = ["templates"].
Сборка в CI (сам контракт)¶
CI создаёт заготовку из каждого шаблона и компилирует её с закреплёнными версиями. Изменение API, ломающее заготовку, останавливает CI крейта, а не первую сборку у пользователя. Задача проверки:
- устанавливает
cargo-generate, - создаёт заготовку во временном каталоге
(
cargo generate --path templates/<name> --name smoke), - запускает
cargo checkв этой заготовке.
Задача правит заготовку дважды. Сначала она переписывает требование версии на ту, которую собирает,
и только это позволяет разрешиться неопубликованному предрелизу: [patch.crates-io] меняет источник крейта,
но не диапазон версий, а предрелиз в диапазон без предрелиза не попадает. Затем она добавляет сам
[patch.crates-io] с путём к локальной копии ядра. Это та же раскладка с соседними репозиториями,
которой уже пользуется CI брокеров.
Только аддитивные блоки¶
Блоки под фичи только добавляют код: {% else %} и отрицательные ветки {% if not flag %} в
шаблоне запрещены. Тогда заготовка без флагов - строгое подмножество заготовки со всеми фичами, и
один cargo check со всеми фичами на шаблон обнаруживает любое расхождение с API.
С выключенными флагами возможны только ошибки написания шаблона: висящий use, незаполненный слот.
Проверяйте их локально.
Кому что принадлежит¶
- Ядро (
ruststream) владеет только шаблономtemplates/memoryна своём in-memory брокере, поэтомуcargo generateпо умолчанию работает офлайн и без зависимости от крейта брокера. - Крейт брокера владеет шаблонами своих транспортов и проверяет их в своём CI.