info.yml
Конфигурация дашборда info.
Содержание
Заголовок раздела «Содержание»- Назначение
- Структура
- Поля верхнего уровня
- Поля секции
- Типы элементов
- Декоративные элементы
- Шаблонные выражения
footer- Поведение по умолчанию при отсутствии info.yml
- Пример: полный info.yml
- Типичные ошибки
- Связанные команды
Назначение
Заголовок раздела «Назначение»workspace/info.yml объявляет содержимое дашборда dwe info: секции, элементы, условную видимость и шаблонные выражения. CLI рендерит его на каждом вызове dwe info.
Загружается отдельно. Не участвует в трёхслойном мердже.
Структура
Заголовок раздела «Структура»sections: - id: <section-id> title: "Optional Section Title" # shown as a bordered box header items: - type: <item-type> <item-fields>
footer: trueПоля верхнего уровня
Заголовок раздела «Поля верхнего уровня»| Поле | Тип | По умолчанию | Описание |
|---|---|---|---|
sections | list | — | Упорядоченный список определений секций. |
footer | bool | false | Если true, после всех секций рендерится завершающая строка-заголовок таблицы. |
Поля секции
Заголовок раздела «Поля секции»| Поле | Тип | По умолчанию | Описание |
|---|---|---|---|
id | string | — | Уникальный идентификатор секции |
title | string | — | Опциональный заголовок, рендерящийся над списком элементов |
items | list | — | Упорядоченный список определений элементов |
hide_on_empty | bool | false | Полностью пропустить секцию (без заголовка, без рамки), если ни один элемент не прошёл when-фильтрацию. Замечание: у subgroup’ов другой дефолт (true). |
Типы элементов
Заголовок раздела «Типы элементов»| Тип | Рендерится как | Обязательные поля |
|---|---|---|
definition | Строка Label — Value, с опциональной иконкой | name, value |
info | Строка info-цвета | text |
warning | Строка warning-цвета | text |
auto-urls | Динамически сгенерированные URL’ы, организованные по сервисам | — |
auto-hosts | Динамически сгенерированные имена хостов из сервисов | — |
subgroup | Контейнер с опциональным заголовком и вложенными элементами | items |
separator | Пустая строка-разделитель | — |
Все элементы принимают опциональный when: (Go template-выражение). Элементы с falsy when исключаются из рендера. Все элементы поддерживают опциональный булев флаг decorative (см. Декоративные элементы).
Замечание о рендеринге
auto-urlsиauto-hosts: элементыauto-urlsиauto-hostsраскрываются во время рендера (когда выполняетсяdwe info), а не во время загрузки YAML. Раскрытие учитывает текущий конфиг и итерирует включённые сервисы в deploy-порядке, так что дашборд всегда отражает актуальные определения и состояние сервисов.
definition
Заголовок раздела «definition»Пара label + value, рендерится как Label — Value.
- type: definition name: Project value: "{{ .Project.FullName }}" icon: "🔗" indent: 2 when: "{{ .State }}"| Поле | Описание |
|---|---|
name | Текст метки |
value | Текст значения (обычная строка или шаблонное выражение) |
icon | Опциональная эмодзи или символ, подставляемый перед значением. Предпочитайте кодпойнты с Emoji_Presentation=Yes (например, 📦, 🐳, 💾); text-default кодпойнты вроде 🛢, 🗄, ⚙ помечаются dwe validate и отбрасываются во время рендера, чтобы сохранить выравнивание колонок — полный комментарий см. в поле icon в справочнике сервисов. |
indent | Опциональное число ведущих пробелов. Дефолт для definition-элементов — 2; передайте 0, чтобы прижать к левому краю. Отрицательные значения не принимаются. |
when | Условие; элемент скрыт, если falsy |
Информационная текстовая строка.
- type: info text: '127.0.0.1 {{ (index .Services "main").Host "web" }}' indent: 0 when: '{{ (index .Services "adminer").Enabled }}'| Поле | Описание |
|---|---|
text | Текст сообщения (обычная строка или шаблонное выражение) |
indent | Опциональное число ведущих пробелов |
when | Условие; элемент скрыт, если falsy |
warning
Заголовок раздела «warning»Строка-предупреждение (рендерится в warning-цвете).
- type: warning text: "Please add this to your /etc/hosts file:"| Поле | Описание |
|---|---|
text | Текст предупреждения (обычная строка или шаблонное выражение) |
when | Условие; элемент скрыт, если falsy |
auto-urls
Заголовок раздела «auto-urls»Динамически генерирует список URL сервисов из настроенных сервисов проекта. Сервисы объявляют свои хосты и порты в workspace/services/<name>/service.yml; auto-urls рендерит их с опциональной фильтрацией и кастомизацией.
- type: auto-urls include: [app, tool] hide: [varnish] hide_paths: main: ["SPX profiler"] port_via: nginx when: "{{ .Services }}"| Поле | Тип | По умолчанию | Описание |
|---|---|---|---|
include | list | [app, tool] | Типы сервисов для включения: любая комбинация app, tool, infra. |
hide | list | — | Ключи папок сервисов, которые нужно полностью исключить. Неизвестные ключи молча игнорируются. |
hide_paths | map | — | Исключить отдельные суб-пути по ключу сервиса и имени пути (например, main: ["SPX profiler"] скрывает путь “SPX profiler” в сервисе “main”). |
port_via | string | auto-detected | Задаёт, какой сервис использовать как front-прокси для генерации основных URL. Если пусто, авто-детект ищет один включённый сервис type: infra, объявляющий либо ports.http: 80 (http-трафик), либо ports.https: 443 (https-трафик). Явно названные отсутствующие сервисы помечаются dwe validate, а не во время рендера. Авто-детект возвращает «без прокси», если найдено ноль или несколько кандидатов (в этом случае рендерятся только прямые URL localhost:<port>). |
when | string | — | Условие; элемент скрыт, если falsy. |
Примеры авто-детекта port_via:
С авто-детектом (дефолт — без поля port_via:):
# Auto-detects if exactly one infra service has ports.http: 80- type: auto-urls include: [app, tool]В этом случае, если сервис nginx имеет ports: {http: 80}, type: infra и включён, он выбирается автоматически. App- и tool-сервисы тогда рендерятся как proxied URL | localhost:port (если они объявляют собственные порты) или просто proxied URL (если есть только host). Остальные сервисы без авто-детектированного прокси рендерятся только как localhost:port.
С явным переопределением port_via::
# Always use named service as proxy, even if it's not type: infra- type: auto-urls include: [app, tool] port_via: api_gatewayЕсли port_via задан явно, но указывает на несуществующий сервис, dwe info молча рендерит без прокси (прямые/host-only URL); отсутствующий сервис помечается только dwe validate (SeverityError). Названный сервис используется для построения прокси-URL независимо от его type:.
Если авто-детект находит ноль или несколько infra-сервисов с целевым портом, прокси не выбирается и сервисы рендерятся только со своими прямыми портами (или только с хостами, если порт отсутствует):
# No eligible infra service found → app/tool with only localhost:<port> URLs- type: auto-urls include: [app, tool]Сервисы участвуют в auto-urls через свой блок info: в service.yml (схема — в services/index.md). Каждый сервис может объявить:
title— переопределяет заголовок сервиса (по умолчанию — title-cased имя папки)primary_host— какую записьhostsподнимать как основной URL (дефолт:web)primary_port— какую записьportsподнимать (дефолт:http)paths— упорядоченный список суб-путей под основным URL
Сервисы без блока info включаются в типы include, но рендерят только свой основной URL, если присутствуют хосты и порты.
Правила сборки URL:
hosts[primary_host]иports[primary_port](прямой биндинг) →<proxied URL> | <direct URL>- только
hosts[primary_host]→<proxied URL>(еслиport_viaдоступен) - только
ports[primary_port]→http://localhost:<port> - ни того, ни другого → строка молча пропускается
<proxied URL> использует порты сервиса port_via для выбора схемы/порта, но info.scheme самого маршрутизируемого сервиса (если задан) имеет более высокий приоритет и также задаёт, какой listener прокси (http или https) будет использован — полная цепочка приоритета описана в URL’ы через reverse-proxy в services/fields.md. <direct URL> использует собственный порт сервиса. Внутри <proxied URL> порты :80 (http) и :443 (https) опускаются; <direct URL> всегда показывает свой порт.
auto-hosts
Заголовок раздела «auto-hosts»Динамически генерирует список всех имён хостов из сервисов для конфигурации /etc/hosts.
- type: auto-hosts include: [app, tool, infra] ip: 127.0.0.1 hide: [varnish] when: "{{ .Services }}"| Поле | Тип | По умолчанию | Описание |
|---|---|---|---|
include | list | [app, tool, infra] | Типы сервисов для включения: любая комбинация app, tool, infra. |
ip | string | 127.0.0.1 | IP-адрес, ассоциируемый со всеми именами хостов. Значения здесь не валидируются на формат IP; dwe validate выдаёт предупреждение, если парсинг падает. |
hide | list | — | Ключи папок сервисов для полного исключения. Неизвестные ключи молча игнорируются. |
when | string | — | Условие; элемент скрыт, если falsy. |
Рендерит каждую запись hosts из включённых сервисов в двухколоночной таблице (IP Hostname), сохраняя deploy-порядок, дедуплицируя имена хостов и пропуская пустые значения, литеральный localhost и любой хост *.localhost (они автоматически резолвятся в 127.0.0.1 и не требуют записи в /etc/hosts).
subgroup
Заголовок раздела «subgroup»Элемент-контейнер, группирующий связанные элементы и опционально показывающий заголовок.
- type: subgroup title: "Tools" hide_on_empty: false items: - type: definition name: Adminer icon: "🛢" value: '{{ appURL ((index .Services "adminer").Host "web") ((index .Services "main").Port "http") .Runtime.UseHTTPS }}' when: '{{ (index .Services "adminer").Enabled }}' - type: definition name: RedisInsight icon: "📊" value: '{{ appURL ((index .Services "redis_insight").Host "web") ((index .Services "main").Port "http") .Runtime.UseHTTPS }}' when: '{{ (index .Services "redis_insight").Enabled }}'| Поле | Тип | По умолчанию | Описание |
|---|---|---|---|
title | string | — | Опциональный заголовок subgroup’а (обычная строка или шаблонное выражение). Если пуст, subgroup рендерится без заголовка. |
items | list | — | Обязательное. Упорядоченный список определений дочерних элементов. Может содержать любой тип элемента, включая вложенные subgroup’ы. |
when | string | — | Условие; если falsy, весь subgroup (включая все вложенные элементы) пропускается. Если truthy, каждый дочерний элемент вычисляется по собственному when. |
hide_on_empty | bool | true | Полностью пропустить subgroup, если ни один дочерний элемент не прошёл when-фильтрацию. (Противоположно дефолту секций; у subgroup’ов дефолт — true.) |
decorative | bool | false | Если true, subgroup никогда не считается контентом для родительской проверки hide_on_empty, даже если он производит вывод. |
Subgroup’ы могут быть вложены произвольно.
separator
Заголовок раздела «separator»Пустая строка для разделения контента внутри секции.
- type: separatorБез полей. Полезен, когда между соседними элементами нужен визуальный отступ без введения новой секции.
Декоративные элементы
Заголовок раздела «Декоративные элементы»По умолчанию элементы делятся на две категории: content-элементы, которые засчитываются для видимости секции, и декоративные — нет.
| Тип | Дефолт decorative |
|---|---|
definition | false |
info | false |
warning | false |
subgroup | false |
separator | true |
Флаг decorative на любом типе элемента переопределяет дефолт:
- type: warning text: "Only informational" decorative: true # Makes this warning not count as content- type: separator decorative: false # Makes this separator count as content, keeping the section visibleКогда hide_on_empty: true на секции или subgroup, блок полностью пропускается, если ни один элемент не прошёл и when-фильтрацию, и проверку content-vs-decorative. Блок только с декоративными элементами (или без элементов) всё равно может отрендериться, если у него есть title и hide_on_empty: false.
Шаблонные выражения
Заголовок раздела «Шаблонные выражения»Все поля text, value и when поддерживают синтаксис Go template, вычисляемый поверх разрешённой конфигурации проекта.
Доступные данные шаблона
Заголовок раздела «Доступные данные шаблона»| Выражение | Тип | Описание |
|---|---|---|
{{ .Project.Name }} | string | Имя проекта |
{{ .Project.FullName }} | string | Объединённый префикс + имя |
{{ .State }} | string | Активное состояние (пусто, если нет) |
{{ .Runtime.UseHTTPS }} | bool | HTTPS включён. |
{{ .Runtime.SPX.Path }} | string | Путь SPX-профайлера. |
{{ (index .Services "main").Enabled }} | bool | Включён ли сервис main (обязательные сервисы всегда true). |
{{ (index .Services "main").Container }} | string | Имя контейнера сервиса main. |
{{ (index .Services "main").Port "http" }} | int | Поиск порта по имени. Port(name) — метод на ServiceConfig (возвращает 0, если отсутствует). |
{{ (index .Services "main").Host "web" }} | string | Поиск хоста по имени. Host(name) возвращает "", если отсутствует. |
{{ (index .Services "main").PortScheme "http" }} | string | Per-port переопределение схемы из развёрнутой формы записи. Возвращает "", если переопределение не задано. |
{{ (index .Services "main").EffectiveScheme "http" .Runtime.UseHTTPS }} | string | Резолвит эффективную схему URL ("http" / "https") по цепочке: per-port → info.scheme → runtime.use_https. |
{{ .AppServices }} / {{ .ToolServices }} / {{ .InfraServices }} | map[string]ServiceConfig | Подмножества, отфильтрованные по type: — удобно для {{ range }} по одной категории. |
Функции шаблона
Заголовок раздела «Функции шаблона»Info-шаблонам доступен стандартный набор хелперов DWE-шаблонов: доменный хелпер appURL плюс реестры sprout (std, strings, numeric, slices, maps, regexp, conversion, time, filesystem, semver). Полный справочник хелперов — в Шаблонах.
Пример использования appURL:
value: '{{ appURL ((index .Services "main").Host "web") ((index .Services "main").Port "http") .Runtime.UseHTTPS }}'# → http://laravel.localhost (or https://… when use_https is true)Условия when
Заголовок раздела «Условия when»Поля when принимают любое шаблонное выражение, которое вычисляется в truthy/falsy-значение. Пустая строка, false и 0 — falsy; всё остальное — truthy.
when: "{{ .State }}" # show only when state is non-emptywhen: '{{ (index .Services "adminer").Enabled }}' # show only when adminer is enabledwhen: "{{ .Runtime.SPX.Path }}" # show only when SPX path is setfooter: trueЕсли true, под всеми секциями рендерится строка-футер (обычно показывает help-подсказку).
Поведение по умолчанию при отсутствии info.yml
Заголовок раздела «Поведение по умолчанию при отсутствии info.yml»Если workspace/info.yml не существует, используется встроенная конфигурация по умолчанию. Она рендерит две секции:
- Секция URLs с элементом
auto-urls(дефолтinclude: [app, tool]; без фильтрации) - Секция Hosts с warning и элементом
auto-hosts(дефолтinclude: [app, tool, infra])
Это позволяет проектам без info.yml сразу видеть осмысленный дашборд со связями всех сервисов, целиком построенный из определений сервисов в workspace/services/*/service.yml. Сервисы вносят детали через свои блоки info: (title, paths, ключи host/port). Редактировать info.yml для старта не требуется.
Пустой или полностью закомментированный workspace/info.yml — тот, из которого не декодируется ни один ключ верхнего уровня — трактуется точно как отсутствующий, поэтому встроенный дефолт остаётся активным. Именно на это опирается сгенерированный (целиком закомментированный) info.yml.
Чтобы кастомизировать дашборд, создайте workspace/info.yml со своими sections и items. Как только из файла декодируется любой ключ верхнего уровня, он считается авторским, и встроенный дефолт не используется: намеренный sections: [] рисует пустой дашборд, а не возвращает дефолт, а файл с одним лишь footer: true применяется как написан.
dwe validate различает эти три состояния в config.info — инертный файл (дефолт молча активен) и sections: [] с уровнем Info, авторский дашборд с реальным содержимым — с OK.
Пример: полный info.yml
Заголовок раздела «Пример: полный info.yml»sections: - id: dwe_info items: - type: subgroup title: DWE hide_on_empty: false items: - type: definition name: Project value: "{{ .Project.FullName }}" - type: definition name: State value: "{{ .State }}" when: "{{ .State }}"
- id: urls title: URLs items: # Automatically render all app and tool services with their hosts/ports - type: auto-urls include: [app, tool] hide: [varnish] hide_paths: main: ["SPX profiler"] port_via: nginx
- id: credentials title: Credentials items: - type: subgroup title: Database hide_on_empty: true items: - type: definition name: User value: "{{ .Project.Name }}_user" - type: subgroup title: API Key hide_on_empty: true items: - type: warning text: "Check .env for sensitive credentials"
- id: hosts title: Hosts items: - type: warning text: "Add these to your /etc/hosts:" # Automatically render all service hostnames - type: auto-hosts include: [app, tool, infra]
footer: trueТипичные ошибки
Заголовок раздела «Типичные ошибки»- Голые значения
when:без шаблонного синтаксиса —when: .Stateневалидно; должно бытьwhen: "{{ .State }}". - Отсутствие кавычек вокруг шаблонных выражений — YAML парсит
{{ ... }}как flow-маппинг, если оно без кавычек. Всегда заключайте шаблонные строки в кавычки. - Синтаксис поиска сервиса — Go text/template требует
indexдля доступа к map по строковому ключу:(index .Services "main")возвращаетServiceConfig. Дальше поля структуры идут в PascalCase (.Container,.Enabled), а порты / хосты используют методы-аксессорыPort/Hostс именем порта/хоста в качестве аргумента:(index .Services "main").Port "http". Скобки вокругindex-выражения обязательны, чтобы метод вызывался на возвращённомServiceConfig. - Использование конфигурационных ключей, не выставленных на верхнем уровне — как прямые шаблонные пути вроде
.Project.Nameдоступны только поля, выставленные разрешённой конфигурацией проекта (см. таблицу выше). Пользовательские ключи, добавленные вdefaults.yml, лежат под.Rawи достаются черезindexили точечные пути кRaw(например,index .Raw "myKey"). - Порядок аргументов
appURL— порядок такой:host,port,useHTTPS, затем опциональныйpath. Перестановка port и useHTTPS молча даёт неправильные URL. При линковке инструмента, маршрутизируемого через основной reverse-прокси, комбинируйте имя хоста инструмента с портом основного сервиса:appURL ((index .Services "adminer").Host "web") ((index .Services "main").Port "http") .Runtime.UseHTTPS. hide_on_emptyс декоративными элементами — по умолчанию content-элементы вродеdefinition,infoиwarningзасчитываются для видимости секции, аseparator— нет. Используйте флагdecorative, чтобы переопределить: задайтеdecorative: trueна content-элементе, чтобы исключить его из расчёта видимости, илиdecorative: falseна separator’е, чтобы он засчитывался как контент. Секция сhide_on_empty: trueполностью скрыта, если ни один content-элемент (послеwhen-фильтрации) не прошёл.- Рендеринг футера с
hide_on_empty— приfooter: trueфутер рендерится только если хотя бы одна секция произвела вывод. Если все секции скрыты черезhide_on_empty, футер тоже подавляется.
Связанные команды
Заголовок раздела «Связанные команды»dwe info— рендер полного дашбордаdwe(без аргументов) — показывает встроенную компактную сводку (не изinfo.yml)