| name | colgen |
| description | Colgen — генератор коллекций для Go-структур. Используй при работе с collection.go и конвертерами между слоями. |
Colgen
Upstream: https://github.com/vmkteam/colgen
Docs: https://vmkteam.dev/colgen/
Генерирует коллекции (XxxList []Xxx) с утилитарными методами из директив в collection.go. Также: inline-сниппеты, LLM-режимы.
Директивы
//go:generate colgen — запуск генератора в файле
//colgen:News,Tag — базовая генерация типов + IDs() + Index() (если есть поле ID)
//colgen:News:<Method>[,<Method>...] — дополнительные методы
- Код должен компилироваться перед запуском — парсинг через AST
Методы
| Директива | Эффект |
|---|
NewsID | NewsIDs() []int (если поле ID нестандартное) |
Index(Field) | IndexByField() map[T]News |
UniqueField | уникальные значения (поддерживает *T c nil-check) |
Count(Field) | CountByField(v) int |
Group(Field) | GroupByField() map[T]NewsList; для []T — fan-out |
Fill(Target,Junction) | заполняет связи; режим определяется типом junction |
Cast(Interface) | Interfaces() []Interface через pointer receiver |
Map(pkg) / MapP(pkg) | конструктор NewNewsList(in []pkg.News) NewsList |
map/mapp | то же в lowercase (приватный конструктор) |
Поведение <Field> по типу
- Скаляр
StatusID int → StatusIDs() []int
- Слайс
TagIDs []int → flatten в []int (не [][]int)
- Указатель
Author *Author → []Author с nil-check и разыменованием
Fill — определение режима
Fill(Tags,TagIDs) где TagIDs []int → many-to-many через related.Index() + append
Fill(Author,AuthorID) где AuthorID *int → one-to-one с nil-check
Все FillXxx возвращают ll для чейнинга: news.FillTags(tags).FillAuthor(authors)
Map / MapP — конвертеры между слоями
Требования:
- Проект должен содержать дженерики
Map[T,M] / MapP[T,M] (pointer-версия)
MapP(db) — если NewNews принимает *db.News
map/mapp (lowercase) — приватные конструкторы
- Разное имя в
db-слое: Map(db.News) (полный путь)
- Структура не в базовой директиве → конструктор вернёт
[]News вместо NewsList
- Другой пакет для
Map/MapP: -funcpkg=<pkg> + имя пакета в -imports через запятую
Порядок первой генерации (gotcha)
- Базовые директивы + методы (без Map/MapP)
- Inline-сниппеты конструкторов (
//colgen@NewNews(db))
- Добавить дженерики
Map/MapP в проект
- Только теперь добавить
Map(db) в colgen
Если добавить Map(db) сразу — не скомпилируется (нет NewNews), AST-парсинг упадёт.
Восстановление
Если всё сломалось — удалить *_colgen.go и перегенерировать. Но: если сгенерированные функции уже используются в коде — удаление даст нерабочий код, и генератор не запустится. Временно удалить использования, перегенерировать, вернуть.
Рекомендация: один colgen на пакет, директивы в collection.go.
Inline-сниппеты
//colgen@<Name>(<pkg>) заменяется прямо в файле на тип + конструктор.
Embed-вариант:
type News struct { db.News }
func NewNews(in *db.News) *News { ... }
Full-вариант — явные поля с тегами json:"..." (поле ID получает тег json:"<entityName>Id").
На сложных объектах сниппет может быть невалиден — редактировать вручную.
LLM-режимы
Нужен API-ключ. Отправляется содержимое файла (+ тест) + промт.
//colgen@ai:review → .md с ревью
//colgen@ai:readme → README.md по файлу
//colgen@ai:tests → _test.go
Суффикс (deepseek) или (claude). DeepSeek по умолчанию.
Маркеры
- Generated:
*_colgen.go с // Code generated by colgen; DO NOT EDIT.
- Редактируемые:
collection.go (директивы), файлы inline-сниппетов после первой генерации