Перейти к содержанию

Регенерация и миграции

Описание процесса регенерации проекта и миграций между версиями.

Сохранение пользовательского кода

Уникальная возможность: Перегенерируйте весь проект без потери ваших изменений.

Как работают Disclaimer-маркеры

Каждый сгенерированный файл содержит маркер:

// ==========================================
// GENERATED CODE - DO NOT EDIT ABOVE THIS LINE
// Changes manually made below will not be overwritten by generator.
// ==========================================

Правила:

  1. Код выше маркера регенерируется при каждом запуске
  2. Код ниже маркера сохраняется навсегда
  3. Если нужно изменить сгенерированный код — переместите его ниже маркера

After-marker код как workaround

Код ниже маркера можно использовать, чтобы не ждать закрытия issue в go-project-starter. Например, если шаблон генерирует не тот код, который вам нужен — переопределите поведение ниже маркера.

Правило: каждый такой workaround обязательно должен содержать:

  1. Ссылку на issue в go-project-starter
  2. TODO-комментарий для удаления после закрытия issue
// ==========================================
// GENERATED CODE - DO NOT EDIT ABOVE THIS LINE
// ==========================================

// TODO: удалить после закрытия https://github.com/Educentr/go-project-starter/issues/12
// Workaround: кастомная схема ошибки вместо ErrorDefault
func (h *ogenDefaultError) NewError(ctx context.Context, err error) *oas.ApiErrorStatusCode {
    // ...
}

Это позволяет:

  • Не блокировать разработку — проект работает с нужным поведением сразу
  • Не терять контекст — ссылка на issue объясняет, зачем этот код
  • Вовремя убирать workaround — по закрытии issue TODO напомнит удалить код и перегенерировать проект

Пример

package handler

import (
    "context"
    "net/http"
)

// ==========================================
// GENERATED CODE - DO NOT EDIT ABOVE THIS LINE
// ==========================================

func (h *Handler) CreateUser(ctx context.Context, req *CreateUserRequest) (*User, error) {
    // Ваш код здесь - переживёт регенерацию!

    user := &User{
        Email: req.Email,
        Name:  req.Name,
    }

    // Кастомная валидация
    if err := h.validateBusinessRules(user); err != nil {
        return nil, err
    }

    return h.repo.Create(ctx, user)
}

// Ваши вспомогательные функции
func (h *Handler) validateBusinessRules(user *User) error {
    // ...
}

Workflow регенерации

При изменении OpenAPI/Protobuf

Используйте make generate:

# 1. Изменить api/openapi.yaml
# 2. Регенерировать код
make generate

# Ваш код в handlers.go сохранится

При изменении config.yaml

Запустите генератор повторно:

# 1. Изменить config.yaml
# 2. Предпросмотр изменений (опционально)
go-project-starter --dry-run --config=config.yaml --target=.

# 3. Применить изменения
go-project-starter --config=config.yaml --target=.

Файлы, которые никогда не перезаписываются

  • .gitignore
  • go.mod, go.sum
  • LICENSE.txt
  • README.md
  • .git/ директория

Миграции между версиями

При обновлении генератора на новую версию может потребоваться миграция конфигурации.

Проверка версии

go-project-starter --version

Запуск миграции

go-project-starter migrate --configDir=.project-config

Что делает миграция

  1. Читает текущую конфигурацию
  2. Применяет изменения для устаревших полей:
  3. Переименование полей
  4. Изменение структуры
  5. Удаление deprecated-полей
  6. Сохраняет обновлённую конфигурацию

Пример миграции

# До миграции (старый формат)
rest:
  - name: api
    generator: ogen

# После миграции (новый формат)
rest:
  - name: api
    generator_type: ogen

Добавление новых компонентов

Добавление нового REST транспорта

  1. Добавьте в config.yaml:
rest:
  - name: admin
    path: [./api/admin.yaml]
    generator_type: ogen
    port: 8081
    version: v1
  1. Добавьте в application:
applications:
  - name: api
    transport: [api, admin, sys]
  1. Регенерируйте:
go-project-starter --config=config.yaml

Добавление нового воркера

  1. Добавьте в config.yaml:
workers:
  - name: email_sender
    generator_type: daemon
  1. Добавьте в application:
applications:
  - name: workers
    workers: [telegram_bot, email_sender]
  1. Регенерируйте проект.

Удаление компонентов

При удалении компонента из конфигурации и перегенерации проекта:

  1. Сгенерированные файлы без user code — удаляются автоматически. Генератор определяет устаревшие файлы по наличию disclaimer-маркера и отсутствию в текущем наборе шаблонов.

  2. Сгенерированные файлы с user code — генерация завершается ошибкой. Перенесите свой код в другое место и удалите файл вручную.

  3. Пользовательские файлы (без disclaimer) — не затрагиваются.

При использовании --dry-run устаревшие файлы отображаются в выводе как "Remove obsolete file".

Best Practices

Версионирование конфигурации

Храните config.yaml в Git:

git add config.yaml
git commit -m "Add admin API transport"

Предпросмотр изменений

Используйте --dry-run перед регенерацией:

go-project-starter --dry-run --config=config.yaml --target=.

Регулярная регенерация

Регенерируйте проект после обновления генератора:

go install github.com/Educentr/go-project-starter/cmd/go-project-starter@latest
go-project-starter --config=config.yaml --target=.

Это обеспечит актуальность инфраструктурного кода.