Локализация (i18n)
Перевод пользовательских строк (описания команд, параметры, тексты подтверждений) на разные языки. Этот документ покрывает конфигурацию, формат файлов и валидацию.
Содержание
Заголовок раздела «Содержание»- Обзор
- Разрешение локали
- Расположение файлов
- Синтаксис конфигурации
- Справочник ключей
- Примеры
- Валидация
- Использование
- Поведение при отсутствующих переводах
Что переводится:
- Пользовательских команд:
description,confirmation_textи описания параметров. - Группы команд:
titleиdescription(отображаются в TUI-браузере команд). - Заголовки секций и подписи свойств markdown-генератора (
## Properties,## Parameters,**Working directory**и т. д.).
Что НЕ переводится:
- Собственные описания cobra-команд DWE (
dwe deploy,dwe run,dwe docsи т. д.) — в v1 они остаются английскими. Это применимо только к пользовательским командам проекта и UI-строкам. - Сообщения об ошибках и логи — они машиночитаемые и всегда на английском.
- Длинная продуктовая документация под
docs/reference/— она находится в отдельном неймспейсе.
Ключевой принцип дизайна: YAML-файлы команд остаются на 100% английскими (это канонический источник); переводы хранятся в sidecar-файлах по известной схеме. Авторы и переводчики не мешают друг другу.
Разрешение локали
Заголовок раздела «Разрешение локали»DWE выбирает активную локаль по следующей цепочке приоритетов (от высшего к низшему):
- Флаг
--lang— принимается каждой подкомандойdwe docs(show,list,search,export,generate,llms-txt). Применяется на один вызов, не сохраняется. - Поле
languageв userconfig —DWE_LANGUAGEпереопределяет значение, загруженное из файла userconfig в этом слоте. - Системная переменная окружения
$LANG— парсится в 2-буквенный код (ru_RU.UTF-8→ru;CиPOSIXигнорируются). - По умолчанию:
en(английский).
Коды вроде ru-RU, ru_RU или ru_RU.UTF-8 нормализуются в ru на каждом уровне. Пустые значения и C/POSIX пропускаются, и цепочка продолжается со следующим источником.
Примеры
Заголовок раздела «Примеры»# Высший приоритет: флаг --lang на любой подкоманде docsdwe docs show config/services/fields --lang rudwe docs list --lang rudwe docs generate --lang ru
# Через userconfig (~/.config/dwe/config или .dwe/config)# language: dedwe commands list# → Выбирает немецкий
# Через переменную окружения — переопределяет поле `language` в userconfigDWE_LANGUAGE=fr dwe commands list# → Выбирает французский
# Через системный $LANG (используется только когда не задан флаг/конфиг/env)LANG=es_ES.UTF-8 dwe commands list# → Выбирает испанский
# Когда локаль не задана, используется английскийdwe commands list# → Выбирает английскийРасположение файлов
Заголовок раздела «Расположение файлов»Переводы лежат в YAML-файлах уровня проекта в директории workspace/i18n/. Глобального/пользовательского каталога переводов не существует; переводы — по проекту.
Расположение переводов проекта:
<project>/ workspace/ i18n/ ru.yml # русский de.yml # немецкий fr.yml # французский # ... любой 2-буквенный код языкаОтсутствие директории workspace/i18n/ молча трактуется как пустота — система откатывается на английский.
Синтаксис конфигурации
Заголовок раздела «Синтаксис конфигурации»Файлы переводов используют YAML-синтаксис со строгой валидацией полей — неизвестные ключи вызывают ошибку разбора (отлавливается dwe validate).
Валидный файл (ru.yml):
ui: docs.section.properties: "Свойства" docs.section.command: "Команда"
commands: build.docker: description: "Собрать образ Docker" confirmation_text: "Вы уверены?" params: tag: description: "Тег образа"
groups: build: title: "Сборка" description: "Команды сборки"Невалидный файл (опечатка в имени поля — строгий декод её отлавливает):
commands: build.docker: descripton: "..." # ← опечатка: "descripton" вместо "description" # → ошибка строгого декода при загрузкеСтрогая валидация ловит опечатки рано. Запустите dwe validate, чтобы вынести наружу любые проблемы.
Справочник ключей
Заголовок раздела «Справочник ключей»Ключи ui.* (UI-строки)
Заголовок раздела «Ключи ui.* (UI-строки)»Эти ключи заполняются английской базой, которая поставляется внутри бинарника dwe, и могут переопределяться или расширяться в файлах проекта.
Ключи этого неймспейса идут под блоком ui: в вашем YAML-файле — пишите голое имя ключа без префикса ui.:
ui: docs.section.properties: "Propriétés" docs.property.id: "Identifiant"Заголовки секций (markdown-генератор):
docs.section.properties→ “Properties”docs.section.command→ “Command”docs.section.parameters→ “Parameters”docs.section.context→ “Context”docs.section.environment→ “Environment Variables”docs.section.with→ “With”docs.section.script→ “Script”docs.section.argv→ “Argv”docs.section.files→ “Files”docs.section.steps→ “Steps”
Подписи свойств (в таблицах свойств и inline-описаниях):
docs.property.id→ “ID”docs.property.type→ “Type”docs.property.group→ “Group”docs.property.private→ “Private”docs.property.confirmation→ “Confirmation”docs.property.confirmation_text→ “Confirmation text”docs.property.success_message→ “Success message”docs.property.error_message→ “Error message”docs.property.shell→ “Shell”docs.property.service→ “Service”docs.property.workdir→ “Working directory”docs.property.builtin→ “Builtin”docs.property.compose_args→ “Compose args”docs.property.argv_append_from→ “Argv append from”docs.property.script→ “Script”
Метки workflow (рендеринг секции Steps):
docs.workflow.parallel→ “parallel”docs.workflow.sub_steps→ “sub-steps”
Модальное окно помощи TUI (?-окно в браузере команд и переменных):
tui.help.title→ “Help”tui.help.section.navigation→ “Navigation”tui.help.section.panels→ “Panels”tui.help.section.actions→ “Actions”tui.help.section.general→ “General”tui.help.action.focus.next→ “Focus next panel”tui.help.action.focus.prev→ “Focus previous panel”tui.help.action.help→ “Toggle help”tui.help.action.quit→ “Quit”tui.help.action.nav.up/.down/.left/.right→ “Move up/down/left/right”tui.help.action.nav.top→ “Go to top”tui.help.action.nav.bottom→ “Go to bottom”tui.help.action.nav.page-up/.page-down→ “Page up/down”tui.help.action.filter→ “Filter”tui.help.action.inspect→ “Inspect”tui.help.action.cmd.skip-confirm→ “Skip confirmation”tui.help.action.cmd.force-form→ “Edit parameters”
Метка действия select намеренно не вынесена в ключ — она зависит от режима (Select в браузере команд, Edit в браузере переменных) и берётся из описания привязки, а не из ключа перевода.
Ключи commands.<id>.*
Заголовок раздела «Ключи commands.<id>.*»Команды, определённые проектом (под workspace/commands/), могут иметь переводы. Структура ключа зеркалит ID и структуру команды:
commands: <group>.<name>: # например, "services.main.db.migrate" description: "..." confirmation_text: "..." messages: success: "..." error: "..." params: <paramName>: # например, "force" description: "..." options: <value>: "..." # например, "prod": "Production"Все поля необязательны; опущенные поля откатываются на английские значения из YAML-файла команды. Пример:
# workspace/commands/tools/deploy.yml (английский источник)- id: deploy description: "Deploy the application" confirmation_text: "Deploy now?" messages: success: "Deployment completed successfully" error: "Deployment failed" params: - name: env description: "Environment (dev / prod)"
# workspace/i18n/ru.yml (русский перевод)commands: tools.deploy: description: "Развернуть приложение" # confirmation_text опущен → используется английское "Deploy now?" messages: success: "Развертывание завершено успешно" error: "Развертывание не удалось" params: env: description: "Окружение (разработка / производство)" options: dev: "Разработка" prod: "Производство"Ключи groups.<id>.*
Заголовок раздела «Ключи groups.<id>.*»Группы команд (наборы связанных команд) могут иметь переведённые заголовки и описания:
groups: <groupId>: # например, "services.main.db" title: "..." # заголовок группы description: "..." # описание группыПример:
groups: services.main: title: "Основные сервисы" description: "Управление основными компонентами приложения" services.tools: title: "Инструменты" description: "Утилиты и вспомогательные команды"Примеры
Заголовок раздела «Примеры»Английская база
Заголовок раздела «Английская база»Встроенная английская база включена в каждый бинарник DWE. Вам не нужно создавать workspace/i18n/en.yml, если только вы не хотите переопределить встроенные UI-строки:
# workspace/i18n/en.yml (опционально; обычно не нужен)ui: docs.section.properties: "Properties"
commands: myapp.deploy: description: "Deploy the application"Русский перевод
Заголовок раздела «Русский перевод»Типичный файл русского перевода:
ui: docs.section.properties: "Свойства" docs.section.command: "Команда" docs.section.parameters: "Параметры" docs.section.context: "Контекст" docs.section.environment: "Переменные окружения" docs.section.with: "С" docs.section.script: "Скрипт" docs.section.argv: "Argv" docs.section.files: "Файлы" docs.property.id: "ID" docs.property.type: "Тип" docs.property.group: "Группа" docs.property.private: "Приватный" docs.property.confirmation: "Подтверждение" docs.property.confirmation_text: "Текст подтверждения" docs.property.success_message: "Сообщение об успехе" docs.property.error_message: "Сообщение об ошибке" docs.property.shell: "Shell" docs.property.service: "Сервис" docs.property.workdir: "Рабочая директория" docs.property.builtin: "Встроенная"
commands: myapp.deploy: description: "Развернуть приложение" confirmation_text: "Развернуть?" messages: success: "Приложение успешно развернуто" error: "Развертывание не удалось" params: env: description: "Окружение (dev/prod)" options: dev: "Разработка" prod: "Производство"
myapp.rollback: description: "Откатить развертывание"
groups: myapp: title: "Основное приложение" description: "Команды для управления основным приложением"Валидация
Заголовок раздела «Валидация»Команда dwe validate проверяет файлы переводов на типичные проблемы:
-
Ошибки разбора — строгая YAML-валидация ловит опечатки в именах полей (например,
descripton:вместоdescription:). Исправьте файл и перезапуститеdwe validate. -
Сиротские записи — перевод ссылается на команду или группу, которой больше нет в
workspace/commands/. Это предупреждение (перевод безвреден, но не используется). Удалите сиротскую запись или переименуйте её, чтобы она соответствовала существующей команде. -
Неизвестные UI-ключи — ключ
ui.*, которого нет в каноническом whitelist’е. Это предупреждение. Если ключ намеренный (например, кастомная UI-строка для будущей фичи), заведите запрос в issue-трекере проекта, чтобы добавить его в whitelist.
Пример вывода валидации:
$ dwe validateDiagnostics: 3 warnings, 0 errors
i18n.orphan [warning] workspace/i18n/ru.yml Translation references command "old.command" that no longer exists Hint: Rename or remove the entry
i18n.unknown_ui_key [warning] workspace/i18n/ru.yml Unknown ui key "ui.custom.label" Hint: Unknown ui key; if intentional, file a request to add it to the canonical set
No errors detected.Все предупреждения информационные. Чтобы они блокировали CI, используйте dwe validate --strict.
Использование
Заголовок раздела «Использование»Переменные окружения
Заголовок раздела «Переменные окружения»DWE_LANGUAGE подставляется в загрузчик userconfig на старте; он перекрывает любое значение language, которое задано в ~/.config/dwe/config или в локальном конфиге проекта. Стоит ниже явного флага --lang и выше системной переменной $LANG:
# Переопределить язык для одной команды (env побеждает userconfig и $LANG)DWE_LANGUAGE=ru dwe commands list
# Закрепить на сессию shellexport DWE_LANGUAGE=dedwe commands list # → немецкий
# Явный --lang всё равно побеждает DWE_LANGUAGEDWE_LANGUAGE=de dwe docs show config/services/fields --lang ru# → Рендерится на русскомФлаг docs generate —lang
Заголовок раздела «Флаг docs generate —lang»Сгенерировать документацию на определённом языке:
# Сгенерировать немецкую документациюdwe docs generate --lang de
# Документация записывается в docs/reference/commands/de/# Английская документация — в docs/reference/commands/en/Флаг --lang принимает любой 2-буквенный код языка. Если локаль недоступна в вашем проекте, DWE откатывается на английский. Сгенерированная документация всегда живёт под commands/<lang>/.
Область и ограничения
Заголовок раздела «Область и ограничения»Пользовательские команды и сгенерированная документация командного справочника локализуются через YAML-стор, описанный выше. Длинная справочная документация под docs/reference/ использует отдельный markdown-неймспейс (см. Переводы длинной документации ниже).
Собственные описания cobra-команд DWE (dwe deploy, dwe run, dwe docs, …) и сообщения об ошибках во время выполнения остаются английскими.
Поведение при отсутствующих переводах
Заголовок раздела «Поведение при отсутствующих переводах»Отсутствующие файлы языков:
- Если
workspace/i18n/не существует, все переводы откатываются на английский. - Если
workspace/i18n/ru.ymlотсутствует, ноLANG=ru_RU.UTF-8, DWE откатывается на английский (молча; без предупреждения).
Отсутствующие отдельные ключи:
- Если файл перевода содержит
commands.deploy.description, но неcommands.deploy.confirmation_text, текст подтверждения остаётся английским. - Если ключ
ui.*отсутствует, используется английский откат.
Эта плавная деградация гарантирует, что частичные переводы всегда работают корректно — переведённые и непереведённые строки сосуществуют в одном интерфейсе.
Переводы длинной документации
Заголовок раздела «Переводы длинной документации»DWE разделяет локализацию на два различных неймспейса:
- Строки команд/UI (этот документ): YAML-файлы под
workspace/i18n/<lang>.yml. Переводы описаний команд, параметров, UI-кнопок и заголовков секций сгенерированной документации. - Длинный markdown: markdown-файлы под
docs/i18n/<lang>/reference/...,docs/i18n/<lang>/guides/...иdocs/i18n/<lang>/internals/.... Переводы встроенной справочной документации, ориентированных на задачи руководств и архитектурных заметок.
Эти неймспейсы используют разные загрузчики, разные валидаторы и разные форматы файлов. Они НЕ сливаются и не разделяют переводы.
Структура и раскладка файлов
Заголовок раздела «Структура и раскладка файлов»Встроенная (английская):
docs/ reference/ # пользовательский справочник config/ workspace.md services/ index.md fields.md ... ... guides/ # ориентированные на задачи руководства add-a-service.md daily-workflow.md ... internals/ # архитектурные и контрибьюторские документы packages.md architecture.md ...Переводы:
docs/ i18n/ ru/ # русский reference/ # зеркалит docs/reference/ config/ workspace.md # русский перевод services/ index.md fields.md guides/ # зеркалит docs/guides/ add-a-service.md internals/ # зеркалит docs/internals/ packages.md de/ # немецкий reference/ config/ workspace.md internals/ ... fr/ # французский (и т. д.) ...Каждый переведённый файл — это самостоятельный markdown-файл в том же месте, что и его английский аналог, но под директорией i18n/<lang>/. Все три дерева — reference/, guides/ и internals/ — включены в манифест устаревания и проходят одну и ту же проверку хэша контента во время выполнения.
Формат заголовка с хэшем контента
Заголовок раздела «Формат заголовка с хэшем контента»Переведённые markdown-файлы включают строку-заголовок, которая фиксирует, когда перевод был в последний раз синхронизирован с английской версией:
> Translated from: config/workspace @ ec4f57457d87
# DWE Configuration
...Формат:
> Translated from: <relative-path> @ <hash><relative-path>— путь к английскому файлу-источнику относительноdocs/(например,reference/config/workspace,internals/architecture). Расширение.mdопускается.<hash>— первые 12 символов SHA256-хэша от байтов контента английского файла-источника.
Пример правильно отформатированного заголовка:
> Translated from: reference/config/services/index @ ec4f57457d87
# Services Configuration
This section describes how to configure services...Вычисление хэша и проверка устаревания
Заголовок раздела «Вычисление хэша и проверка устаревания»Как вычисляется хэш:
- Процесс сборки DWE (
make build) обходитdocs/reference/,docs/guides/иdocs/internals/(плюс корневойREADME.mdрепозитория). - Для каждого markdown-файла он вычисляет
sha256(file_bytes)и берёт первые 12 hex-символов. - Эти хэши встраиваются в бинарник
dweкак манифест. - Манифест коммитится в репозиторий, чтобы каждый бинарник, собранный из одного и того же исходного кода, видел одни и те же хэши.
Почему хэш контента, а не git commit SHA:
- Хэш контента стабилен при ребейзах, cherry-pick’ах и переименованиях файлов. Git SHA меняется при каждом ребейзе.
- Хэш контента работает на свежих чекаутах из tarball (нет директории
.git/). Git SHA требует локальной истории git. - Хэш контента прозрачен для переводчиков: они могут вычислить и вставить хэш без знания
git.
Проверка устаревания во время выполнения:
- Когда вы просматриваете переведённый документ через
dwe docs show,dwe docs exportили TUI, DWE читает переведённый файл и парсит заголовок с хэшем контента (regex:^>\s*Translated from:\s*\S+\s*@\s*([0-9a-f]{12,64})\s*$). - Он сравнивает разобранный хэш с встроенным манифестом.
- Если совпадают → перевод актуален (без баннера).
- Если отличаются → перевод устарел (показан info-баннер).
- Если запись манифеста отсутствует или пуста → проверка отключена (без баннера); это страховка для новых файлов или пустого манифеста на свежем чекауте.
Пользовательский опыт:
- Актуальный перевод: Рендерится как есть, без баннера.
- Устаревший перевод: Рендерится с предупреждающим баннером. Точная формулировка зависит от контекста (фактические значения хэша контента в баннер не подставляются):
- В TUI-браузере:
⚠ This translation is outdated (last synced at previous version, current is newer). Press `e` to view the English version.
- В
dwe docs show/dwe docs export:⚠ Warning: This translation is outdated. Use `--lang en` to view the English version.
- В TUI-браузере:
- Отсутствующий перевод: Рендерится английская версия с info-баннером:
ℹ Translation not available for `ru`. Showing English version.
Workflow переводчика
Заголовок раздела «Workflow переводчика»Чтобы добавить или обновить перевод длинного markdown’а:
-
Скопируйте английский файл:
Окно терминала cp docs/reference/config/services/index.md docs/i18n/ru/reference/config/services/index.mdcp docs/reference/config/services/fields.md docs/i18n/ru/reference/config/services/fields.md -
Переведите контент (сохраните заголовок):
> Translated from: reference/config/services/index @ <english-hash># Конфигурация сервисов... -
Получите английский хэш — первые 12 hex-символов от
sha256(file_bytes):Окно терминала sha256sum docs/reference/config/services/index.md | cut -c1-12# Вывод: a1b2c3d4e5f6 -
Обновите заголовок:
> Translated from: reference/config/services/index @ a1b2c3d4e5f6 -
Создайте pull request с обоими файлами — исходным и переведённым. CI проверяет, что хэш из заголовка соответствует встроенному манифесту.
Разрешение локали для длинной документации
Заголовок раздела «Разрешение локали для длинной документации»Когда вы запускаете dwe docs show, dwe docs list, dwe docs export или пользуетесь TUI, активная локаль определяется так:
- Флаг
--lang(только подкоманды docs; например,dwe docs show config/services/fields --lang ru) - Переменная окружения
DWE_LANGUAGE - Настройка
languageв userconfig - Системный
$LANG(парсится в 2-буквенный код) - По умолчанию:
en
Важно: Разрешение локали для документации не зажато (unclamped). Строки команд/UI используют зажатую локаль (из YAML-стора переводов), а длинные документы используют сырой код локали, чтобы искать в дереве docs/i18n/<lang>/.... Это позволяет иметь разные уровни завершённости переводов в каждом неймспейсе: у вас могут быть французские переводы команд, но только английские длинные документы.
Валидация
Заголовок раздела «Валидация»Команда dwe validate сейчас НЕ проверяет переводы длинного markdown’а (см. ниже «Связанные команды»). Несоответствия формата заголовка и хэша всплывают во время выполнения, когда вы просматриваете документацию, а не во время валидации.
Последующий трек (домен docs.* в фреймворке валидации) запланирован на v2, чтобы выносить устаревшие переводы во время CI, но v1 держит валидацию простой (только строки команд/UI).
Связанные команды
Заголовок раздела «Связанные команды»dwe docs show <topic>— отображает документацию с автоматическим откатом по языкуdwe docs list— перечисляет доступные темы и языкиdwe docs export <dir> [--lang <code>]— экспортирует документацию с пофайловым откатомdwe docs cache clear— очищает кеш mermaid-диаграммdwe docs— открывает интерактивный TUI-браузерdwe commands list— отображает описания команд в активной локалиdwe commands <id>— показывает переведённые детали команды и тексты подтвержденияdwe docs generate --lang <code>— генерирует документацию на конкретном языкеdwe validate— проверяет файлы переводов (только строки команд/UI; валидация длинной документации запланирована)