компоненты как адресат сборки и плоский набор
- компонент — область репозитория, где выбранные слои действуют одновременно; сборка идёт по разу на компонент, у каждого своя директория копий, подписка и локальная часть, секции [components.<имя>] в манифесте - плоский набор описан как низкий конец модели, а не отдельный режим: тема с одним слоем собирается копированием, ключи оси и lang/stack не пишутся - в TODO заведён вопрос о реестре значений осей и судьбе extends:
This commit is contained in:
@@ -143,6 +143,8 @@ code in this repository.
|
|||||||
- META-33: правило стоит в теме, чей вопрос оно решает. Тема — решение, а не
|
- META-33: правило стоит в теме, чей вопрос оно решает. Тема — решение, а не
|
||||||
вещество: «время» проходит через несколько решений сразу, и правило о
|
вещество: «время» проходит через несколько решений сразу, и правило о
|
||||||
колонках БД принадлежит схеме, а не времени.
|
колонках БД принадлежит схеме, а не времени.
|
||||||
|
- META-37: имя темы называет решение и адресата, а не роль части проекта:
|
||||||
|
`logging` и `client-logging`, но не `logging-backend`/`logging-frontend`.
|
||||||
- META-34: тема нужна потребителю целиком — подписка берёт её без остатка.
|
- META-34: тема нужна потребителю целиком — подписка берёт её без остатка.
|
||||||
Если два правдоподобных потребителя хотят непересекающиеся части, между
|
Если два правдоподобных потребителя хотят непересекающиеся части, между
|
||||||
ними и проходит граница.
|
ними и проходит граница.
|
||||||
@@ -160,6 +162,21 @@ code in this repository.
|
|||||||
потребителей. `extends: arch/<файл>.md` в шапке — документация связи, а не
|
потребителей. `extends: arch/<файл>.md` в шапке — документация связи, а не
|
||||||
механизм; слой только реализует и сужает базу, но не отменяет её (META-35).
|
механизм; слой только реализует и сужает базу, но не отменяет её (META-35).
|
||||||
|
|
||||||
|
META-38: ось объявлена в шапке ключами `lang:` и `stack:`, а не выведена из
|
||||||
|
пути; без обоих ключей файл — базовый слой темы. Директория повторяет
|
||||||
|
объявленное для человека. Осей может не быть вовсе: набор, где у темы один
|
||||||
|
слой, — низкий конец той же модели, а не особый режим.
|
||||||
|
|
||||||
|
## Компоненты
|
||||||
|
|
||||||
|
Компонент — область репозитория, где все выбранные слои действуют
|
||||||
|
одновременно (`sqlite` и `postgres` — да, go и javascript — никогда). Уровней
|
||||||
|
три: набор → проект → компонент. Сборка прогоняется по разу на компонент, у
|
||||||
|
каждого своя директория копий, своя подписка и своя локальная часть; в
|
||||||
|
`.conventions.toml` они записаны секциями `[components.<имя>]` с ключами
|
||||||
|
`dir`, `lang`, `stack`, `topics`. Компонент пишется всегда, даже когда он
|
||||||
|
один. Директории компонентов различны — этим копии и разводятся.
|
||||||
|
|
||||||
## Оформление файла
|
## Оформление файла
|
||||||
|
|
||||||
Шапка `topic:` и `prefix:` (плюс `extends:`) → `# Тема` → вводная проза →
|
Шапка `topic:` и `prefix:` (плюс `extends:`) → `# Тема` → вводная проза →
|
||||||
|
|||||||
@@ -53,13 +53,27 @@ conventions/
|
|||||||
stack/<стек>/ привязка к инструменту, хранилищу, транспорту
|
stack/<стек>/ привязка к инструменту, хранилищу, транспорту
|
||||||
```
|
```
|
||||||
|
|
||||||
Оси — раскладка **канона**; в репозитории копия лежит плоско, файлом на
|
Ось файл **объявляет в шапке**, а не наследует от директории (META-38):
|
||||||
тему. Пути файлов даются относительно `conventions/`
|
|
||||||
(`arch/db-identifiers.md`) и адресуют исходник канона, а не место в копии.
|
```yaml
|
||||||
На **правила** ссылаются идентификатором без пути: `KEYS-5`. Префикс
|
topic: logging
|
||||||
уникален по всему канону (он перечислен в манифесте набора), поэтому
|
prefix: SLOG
|
||||||
идентификатор не зависит ни от оси, ни от того, как собран файл у
|
lang: go
|
||||||
потребителя.
|
```
|
||||||
|
|
||||||
|
Ключей оси нет — базовый слой темы. Слова те же, что в подписке потребителя
|
||||||
|
(`lang`, `stack`), так что переводить между двумя сторонами нечего. Дерево
|
||||||
|
директорий повторяет объявленное для человека и остаётся раскладкой
|
||||||
|
**канона**: в репозитории копия лежит плоско, файлом на тему. Пути файлов
|
||||||
|
даются относительно `conventions/` (`arch/db-identifiers.md`) и адресуют
|
||||||
|
исходник канона, а не место в копии. На **правила** ссылаются идентификатором
|
||||||
|
без пути: `KEYS-5`. Префикс уникален по всему канону (он перечислен в
|
||||||
|
манифесте набора), поэтому идентификатор не зависит ни от оси, ни от того, как
|
||||||
|
собран файл у потребителя.
|
||||||
|
|
||||||
|
Объявление вдобавок выражает то, чего дерево не умеет: слой, осмысленный
|
||||||
|
только при совпадении языка и инструмента сразу (`lang: go` и `stack: slog` в
|
||||||
|
одной шапке).
|
||||||
|
|
||||||
Тест — по тому, замена чего убивает правило:
|
Тест — по тому, замена чего убивает правило:
|
||||||
|
|
||||||
@@ -84,6 +98,31 @@ conventions/
|
|||||||
пласт `stack/sqlite/` (типы колонок). Это не принцип, а незавершённая
|
пласт `stack/sqlite/` (типы колонок). Это не принцип, а незавершённая
|
||||||
работа.
|
работа.
|
||||||
|
|
||||||
|
## Плоский набор
|
||||||
|
|
||||||
|
Осей может не быть вовсе. Набор, где у каждой темы ровно один слой, — не
|
||||||
|
особый режим, а низкий конец той же модели: сборка «база → язык → стек»
|
||||||
|
на нём даёт просто копию файла.
|
||||||
|
|
||||||
|
```
|
||||||
|
conventions/
|
||||||
|
logging.md topic: logging, prefix: LOGS
|
||||||
|
errors.md topic: errors, prefix: ERRS
|
||||||
|
time.md topic: time, prefix: TIME
|
||||||
|
```
|
||||||
|
|
||||||
|
Ключей оси в шапках нет, `lang` и `stack` в подписке не пишутся — выбирать
|
||||||
|
не из чего. Так дешевле начинать и так выглядит чужой набор, которому три оси
|
||||||
|
объяснять незачем, чтобы записать пять правил.
|
||||||
|
|
||||||
|
Цена платится при росте, и она не в инструменте: когда плоская тема
|
||||||
|
расслаивается, уехавшие в новый файл правила получают новый префикс и новую
|
||||||
|
нумерацию. Смягчается это тем, что уехавшее правило остаётся на месте
|
||||||
|
заглушкой СНЯТО с новым адресом в причине (META-31, META-32), и тем, что
|
||||||
|
резать нужно правильной стороной: база остаётся в исходном файле со своими
|
||||||
|
идентификаторами, а наружу уезжает специфичное. Если второй язык виден
|
||||||
|
заранее, дешевле сразу разложить по осям.
|
||||||
|
|
||||||
## Темы
|
## Темы
|
||||||
|
|
||||||
**Тема — набор правил об одном фокусе разработки:** время, конфигурация,
|
**Тема — набор правил об одном фокусе разработки:** время, конфигурация,
|
||||||
@@ -109,6 +148,13 @@ prefix: KEYS
|
|||||||
репозиториях — в шапке `origin:` каждой копии, в подписке манифеста, в тексте
|
репозиториях — в шапке `origin:` каждой копии, в подписке манифеста, в тексте
|
||||||
ссылок, — и выданное второй теме начинает указывать на другой набор правил.
|
ссылок, — и выданное второй теме начинает указывать на другой набор правил.
|
||||||
|
|
||||||
|
Раз имя вечно, называют тему **решением и его адресатом**, а не ролью части
|
||||||
|
конкретного проекта (META-37). Логи сервера и логи браузера — это `logging` и
|
||||||
|
`client-logging`, а не `logging-backend` и `logging-frontend`: роль
|
||||||
|
принадлежит сегодняшнему устройству одного репозитория и молча начинает врать,
|
||||||
|
а суффиксная пара вдобавок навязывает чтение «две разновидности одного», хотя
|
||||||
|
по границе темы это разные решения — общего у них три правила из сорока.
|
||||||
|
|
||||||
## Префиксы
|
## Префиксы
|
||||||
|
|
||||||
Каждый файл канона объявляет в шапке свой префикс правил:
|
Каждый файл канона объявляет в шапке свой префикс правил:
|
||||||
@@ -143,24 +189,60 @@ extends: arch/db-identifiers.md
|
|||||||
репозиторий на базу просто не подписан.
|
репозиторий на базу просто не подписан.
|
||||||
|
|
||||||
`extends` — документация связи, а не механизм: за тем, чтобы база лежала
|
`extends` — документация связи, а не механизм: за тем, чтобы база лежала
|
||||||
рядом, никто не следит.
|
рядом, никто не следит. С объявленной осью база к тому же находится сама —
|
||||||
|
это слой той же темы без ключей `lang` и `stack`, — так что ключ остаётся
|
||||||
|
подсказкой человеку и ничего не выбирает.
|
||||||
|
|
||||||
|
## Компонент — адресат сборки
|
||||||
|
|
||||||
|
Подписка принадлежит репозиторию, а собранный документ адресован не
|
||||||
|
репозиторию, а куску кода. Пока проект однороден, разницы нет; два языка её
|
||||||
|
проявляют: `lang = ["go", "javascript"]` склеили бы в один файл го-слой и
|
||||||
|
js-слой, из которых к правимому коду относится ровно половина.
|
||||||
|
|
||||||
|
**Компонент — область репозитория, где все выбранные слои действуют
|
||||||
|
одновременно.** `sqlite` и `postgres` в теме схемы действуют вместе — разные
|
||||||
|
таблицы одного сервиса; го-слой и js-слой не действуют вместе никогда, потому
|
||||||
|
что строка кода написана на чём-то одном. Компонент поэтому совпадает с тем,
|
||||||
|
у чего один язык, один набор инструментов и один вид приложения (META-36).
|
||||||
|
|
||||||
|
Уровней в модели становится три: набор → проект → компонент. Сборка не
|
||||||
|
меняется — та же линейка «база → язык → стек», прогнанная по разу на
|
||||||
|
компонент.
|
||||||
|
|
||||||
## Копия в репозитории
|
## Копия в репозитории
|
||||||
|
|
||||||
Копия плоская: **один файл на тему**, слои осей идут внутри него секциями в
|
Копия плоская: **один файл на тему**, слои осей идут внутри него секциями в
|
||||||
порядке `arch` → язык → стек. Пути канона в копии не воспроизводятся.
|
порядке база → язык → стек. Пути канона в копии не воспроизводятся. Каждый
|
||||||
|
компонент получает свою директорию:
|
||||||
|
|
||||||
```
|
```
|
||||||
docs/conventions/
|
.conventions.toml
|
||||||
|
backend/docs/conventions/
|
||||||
README.md собственный, не собирается
|
README.md собственный, не собирается
|
||||||
READING.md как читать конвенцию — приезжает из канона
|
READING.md как читать конвенцию — приезжает из канона
|
||||||
|
logging.md база + lang/go + stack/slog
|
||||||
time.md arch/time.md + lang/go/time.md
|
time.md arch/time.md + lang/go/time.md
|
||||||
db-identifiers.md arch/db-identifiers.md + lang/go/db-identifiers.md
|
web/docs/conventions/
|
||||||
app-directories.md arch/… + stack/ansible/…
|
READING.md
|
||||||
|
client-logging.md база + lang/javascript + stack/express
|
||||||
```
|
```
|
||||||
|
|
||||||
Так конвенция остаётся самодостаточным документом: тот, кто проверяет по ней
|
Так конвенция остаётся самодостаточным документом: тот, кто проверяет по ней
|
||||||
код — человек или агент, — читает один файл и не собирает тему из трёх мест.
|
код — человек или агент, — читает один файл и не собирает тему из трёх мест.
|
||||||
|
При одном компоненте это ровно прежняя раскладка — `docs/conventions/` в
|
||||||
|
корне.
|
||||||
|
|
||||||
|
Директории компонентов различны, и это единственное, что разводит копии:
|
||||||
|
`logging.md` двух компонентов — разные файлы с одинаковым `origin: logging`,
|
||||||
|
и какой из них какой, сборщик знает по манифесту, а читатель — по пути.
|
||||||
|
Локальные части у них независимы, ради чего всё и затевается: правило,
|
||||||
|
механизированное линтером в go-компоненте, в js-компоненте не механизировано,
|
||||||
|
и один общий файл этого не записал бы.
|
||||||
|
|
||||||
|
`READING.md` лежит рядом с копиями, то есть по одному на компонент. Файл
|
||||||
|
генерируемый, а директория с правилами обязана объяснять себя тому, кто в неё
|
||||||
|
попал.
|
||||||
|
|
||||||
Имена в директории делятся на три вида: `README.md` принадлежит репозиторию и
|
Имена в директории делятся на три вида: `README.md` принадлежит репозиторию и
|
||||||
сборщик его не трогает, `READING.md` принадлежит канону и перезаписывается
|
сборщик его не трогает, `READING.md` принадлежит канону и перезаписывается
|
||||||
@@ -230,7 +312,7 @@ MIGR-6 не соблюдается в `show_history`, `queue`: составны
|
|||||||
| Файл | Где лежит | Что описывает |
|
| Файл | Где лежит | Что описывает |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| `suite.toml` | в наборе | сам набор: язык, темы, префиксы правил |
|
| `suite.toml` | в наборе | сам набор: язык, темы, префиксы правил |
|
||||||
| `.conventions.toml` | в проекте | подключение: откуда копии, какие темы, язык, стек |
|
| `.conventions.toml` | в проекте | подключение: откуда копии, компоненты и их подписки |
|
||||||
|
|
||||||
Манифест набора — единственное место, где перечислены оба идентификатора
|
Манифест набора — единственное место, где перечислены оба идентификатора
|
||||||
канона; правила у них общие, поэтому и файл один. Манифест подключения
|
канона; правила у них общие, поэтому и файл один. Манифест подключения
|
||||||
@@ -239,17 +321,29 @@ MIGR-6 не соблюдается в `show_history`, `queue`: составны
|
|||||||
```toml
|
```toml
|
||||||
source = "ssh://git@git.vakhrushev.me:2222/av/dev-conventions.git"
|
source = "ssh://git@git.vakhrushev.me:2222/av/dev-conventions.git"
|
||||||
|
|
||||||
|
[components.backend]
|
||||||
|
dir = "backend/docs/conventions"
|
||||||
lang = ["go"]
|
lang = ["go"]
|
||||||
stack = ["sqlite", "htmx"]
|
stack = ["slog", "sqlite"]
|
||||||
|
topics = ["logging", "errors", "time"]
|
||||||
|
|
||||||
topics = ["time", "config", "db-identifiers"]
|
[components.web]
|
||||||
|
dir = "web/docs/conventions"
|
||||||
|
lang = ["javascript"]
|
||||||
|
stack = ["express"]
|
||||||
|
topics = ["client-logging"]
|
||||||
```
|
```
|
||||||
|
|
||||||
`lang` и `stack` выбирают строку разреженной матрицы: файл темы собирает
|
`lang` и `stack` выбирают строку разреженной матрицы: файл темы собирает
|
||||||
только те слои, которые репозиторию подходят. `topics` — подписка, именами из
|
только те слои, которые компоненту подходят, и совпадают со словами, которыми
|
||||||
манифеста набора; списка подписчиков у канона по-прежнему нет, список подписок
|
слой объявил свою ось. `topics` — подписка, именами из манифеста набора;
|
||||||
есть
|
списка подписчиков у канона по-прежнему нет, список подписок есть только у
|
||||||
только у потребителя.
|
потребителя.
|
||||||
|
|
||||||
|
Компонент пишется всегда, даже когда он один: сокращённая плоская форма
|
||||||
|
сэкономила бы три строки и завела бы второй способ сказать то же самое.
|
||||||
|
Имя компонента при этом не служебное — им сборщик отвечает, что и куда
|
||||||
|
собрал. У плоского набора `lang` и `stack` в компоненте просто отсутствуют.
|
||||||
|
|
||||||
Как именно инструмент добирается до канона — путь на диске, git, HTTP —
|
Как именно инструмент добирается до канона — путь на диске, git, HTTP —
|
||||||
дело инструмента, а не модели. Манифест отвечает на два вопроса: откуда это
|
дело инструмента, а не модели. Манифест отвечает на два вопроса: откуда это
|
||||||
@@ -265,20 +359,25 @@ topics = ["time", "config", "db-identifiers"]
|
|||||||
любого другого документа. Это главный канал тихого дрейфа, поэтому
|
любого другого документа. Это главный канал тихого дрейфа, поэтому
|
||||||
`AGENTS.md` каждого потребителя должен явно говорить:
|
`AGENTS.md` каждого потребителя должен явно говорить:
|
||||||
|
|
||||||
> Файлы в `docs/conventions/` с шапкой `origin:` — копии из канона
|
> Файлы с шапкой `origin:` в директориях конвенций (пути — в
|
||||||
> `dev-conventions`. Репозиторное пишется только ниже `<!-- conv:local -->`;
|
> `.conventions.toml`) — копии из канона `dev-conventions`. Репозиторное
|
||||||
> всё выше маркера перезаписывается при обновлении. Своё правило — с
|
> пишется только ниже `<!-- conv:local -->`; всё выше маркера
|
||||||
> префиксом на `X`.
|
> перезаписывается при обновлении. Своё правило — с префиксом на `X`.
|
||||||
|
|
||||||
## Команды
|
## Команды
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
conv list # какие темы есть в каноне
|
conv list # какие темы есть в каноне и что подключено
|
||||||
conv add time # добавить тему в манифест и собрать файл
|
conv add time # добавить тему в манифест и собрать файл
|
||||||
|
conv add time --for backend # то же, когда компонентов несколько
|
||||||
conv pull # пересобрать всё, что перечислено в манифесте
|
conv pull # пересобрать всё, что перечислено в манифесте
|
||||||
# (и обновить READING.md рядом с копиями)
|
# (и обновить READING.md рядом с копиями)
|
||||||
|
conv pull --for web # только один компонент
|
||||||
```
|
```
|
||||||
|
|
||||||
|
При одном компоненте `--for` не нужен. При нескольких команда без него не
|
||||||
|
угадывает, а отказывает и перечисляет имена.
|
||||||
|
|
||||||
Отчёт о том, что изменилось, отдельной командой не выдаётся: после `pull`
|
Отчёт о том, что изменилось, отдельной командой не выдаётся: после `pull`
|
||||||
его показывает `git diff`, а решение — принять, поправить или откатить —
|
его показывает `git diff`, а решение — принять, поправить или откатить —
|
||||||
принимает человек перед коммитом.
|
принимает человек перед коммитом.
|
||||||
@@ -315,6 +414,7 @@ conv pull # пересобрать всё, что переч
|
|||||||
прежнюю: зеркальное дерево копий вместо плоского, именованные регионы
|
прежнюю: зеркальное дерево копий вместо плоского, именованные регионы
|
||||||
`<!-- local:имя -->` вместо одного маркера, `origin_hash` в шапке и команды
|
`<!-- local:имя -->` вместо одного маркера, `origin_hash` в шапке и команды
|
||||||
`status`, `diff`, `push`; `READING.md` рядом с копиями он тоже пока не
|
`status`, `diff`, `push`; `READING.md` рядом с копиями он тоже пока не
|
||||||
кладёт. Сами конвенции уже приведены к новой модели — именованных регионов в
|
кладёт, компонентов и объявленной оси не знает и выбирает слои по пути. Сами
|
||||||
каноне нет. Ни один репозиторий-потребитель не
|
конвенции уже приведены к новой модели — именованных регионов в каноне нет,
|
||||||
подключён, поэтому переход никого не ломает.
|
ось объявлена в шапках. Ни один репозиторий-потребитель не подключён, поэтому
|
||||||
|
переход никого не ломает.
|
||||||
|
|||||||
@@ -69,7 +69,25 @@ API, а норму при этом нельзя поправить, не зад
|
|||||||
|
|
||||||
# Канон и подключение
|
# Канон и подключение
|
||||||
|
|
||||||
## 4. Пары слоёв и темы без базы
|
## 4. Значения осей нигде не зарегистрированы
|
||||||
|
|
||||||
|
Ось теперь объявлена в шапке (META-38), но её значения не сверяются ни с чем:
|
||||||
|
`lang: golang` вместо `lang: go` соберётся молча — слой просто не попадёт ни в
|
||||||
|
одну копию. Это ровно та болезнь, от которой лечили тему (META-28): объявление
|
||||||
|
без реестра проверяется только глазами.
|
||||||
|
|
||||||
|
Напрашивается секция в `suite.toml` рядом с `[topics.live]` и
|
||||||
|
`[prefixes.live]` — перечень живых языков и стеков с однострочным описанием, и
|
||||||
|
те же правила выбытия. Против: третий реестр в манифесте, а значений сегодня
|
||||||
|
три (`go`, `ansible`, `htmx`). За: словарь общий у двух сторон — им же
|
||||||
|
потребитель пишет `lang` и `stack` в своём компоненте, и опечатка там стоит
|
||||||
|
столько же.
|
||||||
|
|
||||||
|
Заодно решается судьба `extends:`: с объявленной осью база находится сама —
|
||||||
|
это слой той же темы без ключей оси, — так что ключ остался подсказкой
|
||||||
|
человеку и кандидат на снятие.
|
||||||
|
|
||||||
|
## 5. Пары слоёв и темы без базы
|
||||||
|
|
||||||
Отложено сознательно, но список стоит держать перед глазами:
|
Отложено сознательно, но список стоит держать перед глазами:
|
||||||
|
|
||||||
@@ -90,9 +108,9 @@ API, а норму при этом нельзя поправить, не зад
|
|||||||
- Вынос арх-ядра из `errors` и `logging` закроет две хрупкие ссылки из
|
- Вынос арх-ядра из `errors` и `logging` закроет две хрупкие ссылки из
|
||||||
`web-ui` (стек) в go-слой — единственные ссылки стек → язык в каноне.
|
`web-ui` (стек) в go-слой — единственные ссылки стек → язык в каноне.
|
||||||
|
|
||||||
## 5. Восемь тем не прогнаны по границе
|
## 6. Восемь тем не прогнаны по границе
|
||||||
|
|
||||||
Критерии границы записаны правилами (META-33 … META-36), но ни одна тема по
|
Критерии границы записаны правилами (META-33 … META-37), но ни одна тема по
|
||||||
ним не прочитана. Работа по одной теме: выписать вопрос темы одной фразой и
|
ним не прочитана. Работа по одной теме: выписать вопрос темы одной фразой и
|
||||||
пройти по правилам, помечая чужие.
|
пройти по правилам, помечая чужие.
|
||||||
|
|
||||||
@@ -103,24 +121,24 @@ API, а норму при этом нельзя поправить, не зад
|
|||||||
(20 символов в БД), GTIM-8 и GTIM-9 (UTC и точность в логах) выносят вердикты
|
(20 символов в БД), GTIM-8 и GTIM-9 (UTC и точность в логах) выносят вердикты
|
||||||
тем `db-schema` и `logging`. Остаток — представление момента, единая точка
|
тем `db-schema` и `logging`. Остаток — представление момента, единая точка
|
||||||
«сейчас», длительность и часы, не-UTC на отображении — тема настоящая. Разрез
|
«сейчас», длительность и часы, не-UTC на отображении — тема настоящая. Разрез
|
||||||
попутно снимает `extends: arch/time.md` из вопроса 4.
|
попутно снимает `extends: arch/time.md` из вопроса 5.
|
||||||
|
|
||||||
`logging` лежит целиком в `lang/go`, хотя внутри три страта: уровень по
|
`logging` лежит целиком в `lang/go`, хотя внутри три страта: уровень по
|
||||||
адресату, «ошибка логируется один раз на границе», секреты — не про Go;
|
адресату, «ошибка логируется один раз на границе», секреты — не про Go;
|
||||||
`JSONHandler`, `stdout`, разбор через `jq`/DuckDB — про стек; SLOG-30…33
|
`JSONHandler`, `stdout`, разбор через `jq`/DuckDB — про стек; SLOG-30…33
|
||||||
(входящий запрос, healthcheck, 4xx) — про вид приложения (META-36), то есть
|
(входящий запрос, healthcheck, 4xx) — про вид приложения (META-36), то есть
|
||||||
про веб-сервис. Здесь же лежит невыделенное арх-ядро из вопроса 4.
|
про веб-сервис. Здесь же лежит невыделенное арх-ядро из вопроса 5.
|
||||||
|
|
||||||
Отдельно проверить обратное: `errors` без арх-слоя — не дефект. Обработка
|
Отдельно проверить обратное: `errors` без арх-слоя — не дефект. Обработка
|
||||||
отказа в плейбуке (`failed_when`, `block`/`rescue`, идемпотентность) го-шные
|
отказа в плейбуке (`failed_when`, `block`/`rescue`, идемпотентность) го-шные
|
||||||
правила не сужает, а решает другую задачу, значит для плейбуков это своя
|
правила не сужает, а решает другую задачу, значит для плейбуков это своя
|
||||||
тема, а не слой в `errors` (META-35).
|
тема, а не слой в `errors` (META-35).
|
||||||
|
|
||||||
## 6. Подключение к репозиториям
|
## 7. Подключение к репозиториям
|
||||||
|
|
||||||
Ничего ещё не подключено. Кандидаты — jellybit и pet-project-server.
|
Ничего ещё не подключено. Кандидаты — jellybit и pet-project-server.
|
||||||
Понадобится: заполнить локальную часть копий тем, что сейчас в этих
|
Понадобится: заполнить локальную часть копий тем, что сейчас в этих
|
||||||
репозиториях записано по факту; обёртка в раннере (`inv conventions` /
|
репозиториях записано по факту; обёртка в раннере (`inv conventions` /
|
||||||
`task conventions`, единый интерфейс команд у трёх ansible-репозиториев);
|
`task conventions`, единый интерфейс команд у трёх ansible-репозиториев);
|
||||||
строка в `AGENTS.md` каждого потребителя про то, что файлы в
|
строка в `AGENTS.md` каждого потребителя про то, что файлы в директориях
|
||||||
`docs/conventions/` — копии.
|
конвенций — копии. Компонент у обоих кандидатов один, но записывается явно.
|
||||||
|
|||||||
@@ -28,12 +28,19 @@
|
|||||||
| Уровень | Английский | Русский | Что там лежит |
|
| Уровень | Английский | Русский | Что там лежит |
|
||||||
|---|---|---|---|
|
|---|---|---|---|
|
||||||
| набор | `suite` | набор | `conventions/`, манифест набора, обвязка |
|
| набор | `suite` | набор | `conventions/`, манифест набора, обвязка |
|
||||||
| проект | `project` | проект | `docs/conventions/`, манифест подключения, копии |
|
| проект | `project` | проект | манифест подключения, компоненты |
|
||||||
|
| компонент | `component` | компонент | директория копий: один язык, один стек, один вид приложения |
|
||||||
|
|
||||||
`package`, `bundle`, `library` не берём: они тащат багаж менеджеров
|
`package`, `bundle`, `library` не берём: они тащат багаж менеджеров
|
||||||
зависимостей — версии, разрешение, лок, — которого в модели нет. `set` не
|
зависимостей — версии, разрешение, лок, — которого в модели нет. `set` не
|
||||||
годится в CLI: в позиции подкоманды читается глаголом.
|
годится в CLI: в позиции подкоманды читается глаголом.
|
||||||
|
|
||||||
|
Компонент — адресат сборки: подписка принадлежит проекту, а собранный файл
|
||||||
|
читает тот, кто правит конкретный код. Определение — область, где все
|
||||||
|
выбранные слои действуют одновременно (`sqlite` и `postgres` — да, go и
|
||||||
|
javascript — никогда). Уровнем CLI компонент не становится: это аргумент
|
||||||
|
`--for`, а не подкоманда.
|
||||||
|
|
||||||
«Канон» — имя этого конкретного набора, а не термин уровня; в общих
|
«Канон» — имя этого конкретного набора, а не термин уровня; в общих
|
||||||
формулировках употребляется «набор». «Потребитель» — слово про роль
|
формулировках употребляется «набор». «Потребитель» — слово про роль
|
||||||
репозитория, а не про уровень.
|
репозитория, а не про уровень.
|
||||||
@@ -55,10 +62,15 @@ convy pull пересобрать подписанное
|
|||||||
convy list что подключено и что можно взять
|
convy list что подключено и что можно взять
|
||||||
convy check проверить форму того, что здесь
|
convy check проверить форму того, что здесь
|
||||||
|
|
||||||
convy suite check целостность набора: префиксы, темы, ссылки, форма
|
convy suite check целостность набора: префиксы, темы, оси, ссылки, форма
|
||||||
convy suite new новая тема: шапка, префикс, запись в манифест
|
convy suite new новая тема: шапка, префикс, запись в манифест
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Проектные команды принимают `--for <компонент>`. При одном компоненте флаг не
|
||||||
|
нужен; при нескольких команда без него отказывает и перечисляет имена — тот
|
||||||
|
же принцип, что и с контекстом: наугад не делается ничего. `convy list`
|
||||||
|
группирует вывод по компонентам.
|
||||||
|
|
||||||
Граница проходит не по «проектное против наборного», а по «частое и
|
Граница проходит не по «проектное против наборного», а по «частое и
|
||||||
повсеместное» против «только у автора». Поэтому `check` остаётся наверху:
|
повсеместное» против «только у автора». Поэтому `check` остаётся наверху:
|
||||||
форма правила одна и та же, локальные правила проекта на `X`-префиксах
|
форма правила одна и та же, локальные правила проекта на `X`-префиксах
|
||||||
@@ -84,24 +96,33 @@ convy suite new новая тема: шапка, префикс, запис
|
|||||||
Они расходятся по частоте, по адресату и по тому, что считается провалом.
|
Они расходятся по частоте, по адресату и по тому, что считается провалом.
|
||||||
|
|
||||||
**Целостность набора.** Префиксы уникальны и не переиспользованы, шапка
|
**Целостность набора.** Префиксы уникальны и не переиспользованы, шапка
|
||||||
совпадает с манифестом, тема объявлена и зарегистрирована, у каждого правила
|
совпадает с манифестом, тема объявлена и зарегистрирована, ось объявлена
|
||||||
|
ключами и у темы не больше одного базового слоя, у каждого правила
|
||||||
модальность с нормой и обоснование либо заглушка, нумерация сплошная, ссылки
|
модальность с нормой и обоснование либо заглушка, нумерация сплошная, ссылки
|
||||||
разрешаются, путей набора в тексте конвенции нет, строка о версии языка на
|
разрешаются, путей набора в тексте конвенции нет, строка о версии языка на
|
||||||
месте. Запускается в наборе при каждой правке; провал — ошибка.
|
месте. Запускается в наборе при каждой правке; провал — ошибка.
|
||||||
|
|
||||||
**Установка в проект.** Манифест подключения, сборка файла темы из слоёв,
|
**Установка в проект.** Манифест подключения, сборка файла темы из слоёв на
|
||||||
сохранение локальной части, `READING.md` рядом с копиями. Запускается в
|
каждый компонент, сохранение локальной части, `READING.md` рядом с копиями.
|
||||||
проекте изредка; провал чаще означает «посмотри глазами», чем «ошибка».
|
Запускается в проекте изредка; провал чаще означает «посмотри глазами», чем
|
||||||
Отчёта «набор ушёл вперёд» нет: его делает `git diff` после пересборки.
|
«ошибка». Отчёта «набор ушёл вперёд» нет: его делает `git diff` после
|
||||||
|
пересборки.
|
||||||
|
|
||||||
## Что делает установка
|
## Что делает установка
|
||||||
|
|
||||||
Подробности — в README, раздел «Копия в репозитории». Коротко, что важно для
|
Подробности — в README, раздел «Копия в репозитории». Коротко, что важно для
|
||||||
реализации:
|
реализации:
|
||||||
|
|
||||||
|
- сборка идёт **по разу на компонент**, в директорию `dir` из его секции;
|
||||||
|
директории компонентов обязаны различаться — иначе копии столкнутся
|
||||||
|
именами, и это ошибка манифеста, а не повод переименовывать файлы;
|
||||||
- копия плоская, **один файл на тему**; слои идут секциями в порядке
|
- копия плоская, **один файл на тему**; слои идут секциями в порядке
|
||||||
`arch` → язык → стек, выбор слоёв — по `lang` и `stack` из манифеста
|
база → язык → стек, выбор слоёв — по `lang` и `stack` компонента, сверяемым
|
||||||
подключения;
|
с ключами оси в шапке слоя (META-38), а не с путём файла в наборе; слой без
|
||||||
|
ключей оси — базовый и попадает в копию всегда;
|
||||||
|
- набор может быть плоским: у темы один слой, ключей оси нет, `lang` и
|
||||||
|
`stack` в компоненте отсутствуют. Отдельной ветки в коде это не требует —
|
||||||
|
сборка из одного слоя есть копирование;
|
||||||
- шапка копии — только `origin:` с именем темы; отпечатков и дат нет;
|
- шапка копии — только `origin:` с именем темы; отпечатков и дат нет;
|
||||||
- всё ниже маркера `<!-- conv:local -->` переживает пересборку, всё выше
|
- всё ниже маркера `<!-- conv:local -->` переживает пересборку, всё выше
|
||||||
перезаписывается; маркер ставит сборщик;
|
перезаписывается; маркер ставит сборщик;
|
||||||
|
|||||||
+6
-4
@@ -32,10 +32,12 @@ reading = "READING.md"
|
|||||||
# БД. Имя записывается латиницей; рекомендуется нижний kebab-case, но годится
|
# БД. Имя записывается латиницей; рекомендуется нижний kebab-case, но годится
|
||||||
# любой идентификатор, пригодный для имени файла.
|
# любой идентификатор, пригодный для имени файла.
|
||||||
#
|
#
|
||||||
# Тема — единица подписки и единица сборки: потребитель перечисляет темы в
|
# Тема — единица подписки; собирается она на каждый компонент проекта, все
|
||||||
# своём манифесте, а сборщик складывает в один файл все слои темы в порядке
|
# слои темы в один файл в порядке база → язык → стек. Слои узнают друг друга
|
||||||
# arch → язык → стек. Слои узнают друг друга по объявленному имени, а не по
|
# по объявленному имени, а не по имени файла: файл конвенции несёт тему в
|
||||||
# имени файла: файл конвенции несёт тему в шапке (`topic: time`).
|
# шапке (`topic: time`), а свою ось — ключами `lang:` и `stack:` там же
|
||||||
|
# (META-38). Слой без ключей оси — базовый; тем, у которых слой один,
|
||||||
|
# директории осей не нужны вовсе.
|
||||||
#
|
#
|
||||||
# Имя темы не переименовывается и не переиспользуется: на тему ссылаются
|
# Имя темы не переименовывается и не переиспользуется: на тему ссылаются
|
||||||
# словом — из текста конвенций («конвенция `logging`»), из подписки в
|
# словом — из текста конвенций («конвенция `logging`»), из подписки в
|
||||||
|
|||||||
Reference in New Issue
Block a user