migratorrun

package
v1.4.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 10, 2026 License: Apache-2.0 Imports: 8 Imported by: 0

Documentation

Overview

Package migratorrun — накат цепочки миграций, объявленный ОДИН раз на дерево.

Все семь точек наката (`services/*/cmd/migrator`) применяют миграции через Runner и своей редакции этого шага не держат. Решение и его довод — docs/architecture/migrator-form.md; здесь они не пересказываются.

Что сюда переехало

Один и тот же вопрос — «как этот сервис применяет миграции» — решался в дереве ДВУМЯ формами, и решения об этом не принимал никто: формы разошлись как побочный эффект того, что сервисы заводились в разное время (#1383). Три службы держали собственный пакет-обёртку `internal/apps/migrator` (`Dialect` + `Runner` + `Config.Validate`), четыре звали goose прямо из `main.go`. Три обёртки при этом копиями НЕ были: у двух `Dialect` был интерфейсом, у одной — структурой.

Почему дом здесь, а не в pkg/migratorcli

Решение называет домом общего пакета `pkg/`, и `pkg/migratorcli` уже несёт всё, что базы не касается: разбор аргументов, приоритет источников DSN, предусловия, открытие базы с барьером готовности, настройку goose.

Накат туда не переехал по ОДНОЙ измеренной причине: ему нужен живой счёт строк перед сносом (`pkg/dropguard`), а `pkg/` не имеет НИ ОДНОГО ребра в `internal/` (предикат: `git grep -l 'kacho/internal/' -- pkg ':!*_test.go'` → пусто). Завести первое такое ребро ради одного вызова значило бы принять решение о `pkg/` целиком, никем не принятое, и принять его молча.

Довод содержательный, а не обходной: счёт перед сносом — политика об этом дереве и его цепочках, а не переиспользуемый фундамент. Пакет, которому он нужен, репозиторно-внутренний по природе. Довод самого решения при этом сохранён дословно — общий пакет не лежит внутри одной службы и потому не заводит ребра между службами (ban #8).

Счёт перед сносом стоит ПО ПОСТРОЕНИЮ

Он живёт внутри Runner.Up: обойти его нельзя, не обойдя сам Up. В прямой форме это был отдельный оператор в `main.go`, и его наличие держал гейт — то есть шаг, который зовут отдельной строкой, однажды могли не позвать.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Config

type Config struct {
	// Service — имя службы, чью цепочку применяет накат. Обязательное: без него
	// живой счёт строк перед сносом не может назвать, что он стережёт, а
	// безымянный отказ в логе init-контейнера некому адресовать.
	Service string

	// Dialect — имя диалекта, как его назвал оператор. Пустое имя НЕ означает
	// «умолчание»: разбор аргументов подставляет умолчание сам, поэтому пустая
	// строка сюда доезжает только как явное `--dialect ""` — то есть как
	// названный и неподдерживаемый диалект.
	Dialect string

	// DSN — строка подключения. Резолвит её [migratorcli.ResolveDSN] у всех
	// семи, с одним приоритетом: `--dsn` > [migratorcli.EnvDSN] > конфигурация.
	DSN string

	// FS — файловая система с миграциями (`internal/migrations.FS` службы).
	// Параметром, а не импортом: правило `internal` языка запрещает пакету из
	// корня импортировать `services/<svc>/internal/migrations`.
	FS fs.FS

	// MigrationsDir — путь внутри FS; для корня встроенной — ".".
	MigrationsDir string

	// DSNExtraSources — чем ЭТА служба заполняет DSN СВЕРХ двух общих, в порядке
	// убывания приоритета. Два общих здесь не перечисляются: их печатает
	// [migratorcli.DSNSourceList], поэтому умолчать источник, который перебивает
	// названные, нельзя by construction.
	DSNExtraSources []string
}

Config — параметры одного запуска наката. Заполняет их `cmd/migrator/main.go` каждой службы из разобранных аргументов, окружения и своей конфигурации.

type Runner

type Runner struct {
	// contains filtered or unexported fields
}

Runner — накат цепочки. Один экземпляр на жизнь процесса; параллельное использование не предполагается (goose держит настройку в пакетных глобалках, а командная строка гоняет одну команду за раз).

func New

func New(cfg Config) (*Runner, error)

New собирает Runner, проверив предусловия ДО первого обращения к базе.

Проверки, их порядок и тексты отказа объявлены один раз на дерево — migratorcli.RunnerPreconditions. Здесь они не переобъявляются: своей редакции того же текста завестись негде, потому что Runner в дереве один.

func (*Runner) Down

func (r *Runner) Down(ctx context.Context, target string) error

Down откатывает цепочку: незаданная цель — один шаг назад, заданная — до названной версии включительно.

Счёта перед сносом здесь нет намеренно: откат — заявленный снос, а не побочный. Предмет стража — снос, приезжающий вместе с накатом, о котором оператор не знал.

func (*Runner) Status

func (r *Runner) Status(ctx context.Context, out io.Writer) error

Status печатает применённые и непринятые миграции.

out принимается параметром и ЗДЕСЬ НЕ ЧИТАЕТСЯ: goose v3 пишет в собственный логгер, а перенаправление идёт через goose.SetLogger. Параметр остаётся, чтобы перенаправление, когда его заведут, не меняло подпись у семи вызывающих.

func (*Runner) Up

func (r *Runner) Up(ctx context.Context, target string) error

Up применяет цепочку — сперва СОСЧИТАВ строки в таблицах, которые уронят ещё не применённые миграции В ПРЕДЕЛАХ ЭТОГО ПРОГОНА, и лишь затем применяя. Ненулевой счёт прекращает применение.

Граница прогона разбирается ДО счёта: страж обязан считать ровно те сносы, которые этот прогон ВЫПОЛНИТ, а не все ещё не применённые. Разбор — та же функция, которой читает цель goose, поэтому двух редакций одного числа завестись не может; заодно негодная цель отвергается до соединения с базой.

Обойти счёт цель НЕ ДАЁТ, и это построение, а не обещание: незаданная цель — нулевое значение dropguard.Target, то есть «считать всё», а суженная сужает ровно настолько же и применяемое.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL