maxicfg

Конфигурация

maxicfg ищет файл .maxicfg.yaml в текущем каталоге и поднимается вверх по дереву, пока не найдёт его. Всё в этом файле необязательно — утилита работает и на одних флагах командной строки.

Файл проекта

# .maxicfg.yaml
version: 1

schema: ./config/schema.yaml

profiles:
  local:
    sources: [config/base.yaml, config/local.yaml]
  staging:
    sources: [config/base.yaml, config/staging.yaml]
  production:
    sources: [config/base.yaml, config/production.yaml]

lint:
  strict: true            # неизвестные ключи считать ошибкой
  max_depth: 8

scan:
  ignore:
    - "config/fixtures/**"
    - "**/*.example.yaml"

Источники внутри профиля объединяются слева направо: файлы правее перекрывают левые. Это обычная схема «база плюс наложение», и она означает, что схема должна описывать только итоговый результат слияния.

Синтаксис схемы

Схема — это YAML-файл с одним отображением keys верхнего уровня. Ключи записываются через точку независимо от вложенности в исходном файле.

keys:
  # обязательная строка
  service.name:
    type: string
    required: true
    pattern: "^[a-z][a-z0-9-]{2,40}$"

  # целое число с границами и значением по умолчанию
  server.port:
    type: int
    default: 8080
    min: 1
    max: 65535

  # одно из фиксированного набора значений
  logging.level:
    type: enum
    values: [debug, info, warn, error]
    default: info

  # длительность в синтаксисе Go
  cache.ttl:
    type: duration
    default: 5m

  # маска соответствует любому ключу на этой позиции
  features.*:
    type: bool
    default: false

  # вложенные маски тоже работают
  databases.*.host:
    type: string
    required: true

Поддерживаемые типы

ТипПринимаетДоп. параметры
stringлюбой скалярpattern, min_len, max_len
intцелые числаmin, max
floatчислаmin, max
booltrue, false, yes, no, 1, 0
enumзначения из спискаvalues (обязательно)
duration30s, 5m, 2h30mmin, max
bytes512kb, 4mb, 1gbmin, max
urlабсолютные URLschemes
listпоследовательностиof, min_items, max_items

Шаблонизация

maxicfg render подставляет переменные в файл шаблона. Синтаксис намеренно минимальный: только подстановка переменных и значения по умолчанию, без циклов и условий.

# config/production.yaml.tmpl
database:
  host: ${DB_HOST}
  port: ${DB_PORT:-5432}
  pool_size: ${DB_POOL:-40}

logging:
  level: ${LOG_LEVEL:-info}
$ DB_HOST=db.internal maxicfg render config/production.yaml.tmpl \
    --out config/production.yaml

Переменная без значения и без значения по умолчанию — это ошибка, а не пустая строка. Так сделано намеренно: молча отрендерить пустой хост хуже, чем уронить сборку.

Исключение ключей

Некоторые ключи должны отличаться между окружениями и не должны попадать в дифф. Помечайте их в схеме, а не фильтруйте вывод постфактум:

keys:
  database.password:
    type: string
    required: true
    secret: true          # не печатается, исключён из вывода diff

  deploy.replicas:
    type: int
    environment_specific: true   # исключён из отчётов о расхождениях

Переменные окружения

ПеременнаяДействие
MAXICFG_CONFIGпуть к файлу проекта, отменяет автопоиск
MAXICFG_PROFILEпрофиль по умолчанию, если --profile не указан
MAXICFG_NO_COLORотключить цветной вывод
MAXICFG_LOGdebug включает подробное логирование