Key features implemented: - New i18n module with JSON-based message catalogs for multi-language support - Added Russian (ru-RU) and English (en-US) localization files with 100+ messages - PowerShell module ActivityWatch.Windows.I18n.psm1 with fallback mechanism - Node.js validation and coverage analysis scripts for locale management - Package.json configuration with semantic versioning and build tools - README_RU.md documentation with integration examples and best practices The implementation provides comprehensive internationalization support with automated validation, versioning, and fallback capabilities for robust multilingual deployments.
9.7 KiB
Интернационализация (i18n) в AWatch-rus
Обзор
Модуль интернационализации обеспечивает поддержку многоязычного интерфейса для PowerShell-скриптов проекта AWatch-rus.
Возможности
- JSON-based каталоги сообщений — удобное хранение и редактирование переводов
- Автоматический fallback — при отсутствии перевода используется резервный язык
- Параметризованные сообщения — поддержка форматирования с плейсхолдерами
{0},{1}, etc. - Автоверсионизация — семантическое версионирование каталогов переводов
- Валидация — проверка структуры и консистентности переводов
- Анализ покрытия — отчет о полноте переводов по языкам
Структура
i18n/
├── en-US.json # Reference locale (English)
├── ru-RU.json # Russian translation
├── package.json # Node.js scripts configuration
└── scripts/
├── validate-locales.js # Валидация JSON-файлов
├── check-coverage.js # Анализ покрытия переводов
└── bump-version.js # Автоверсионирование
Быстрый старт
1. Инициализация локали в PowerShell скрипте
# Импортируйте модуль i18n
Import-Module "$PSScriptRoot\ActivityWatch.Windows.I18n.psm1" -Force
# Инициализируйте русскую локаль с английским fallback
Initialize-Locale -Culture "ru-RU" -FallbackCulture "en-US"
# Или автодетект культуры системы
Initialize-Locale -AutoDetect
2. Использование локализованных строк
# Простое сообщение
$message = Get-LocalizedString -Key "errors.admin_required"
# Сообщение с параметрами
$message = Get-LocalizedString -Key "errors.binary_missing" -FormatArgs @("aw-watcher-afk.exe")
# Вывод информации
Get-LocalizedInfo -Key "starting_deployment" -FormatArgs @("v0.13.2")
# Вывод предупреждения
Get-LocalizedWarning -Key "insecure_connection"
# Создание ошибки
$errorRecord = Get-LocalizedError -Key "config_not_found" -FormatArgs @($configPath)
throw $errorRecord
# Статусы
$status = Get-LocalizedStatus -Key "installation_success"
# Подтверждение от пользователя
if (Read-LocalizedConfirm -PromptKey "confirm_install" -FormatArgs @($userCount)) {
# Продолжить установку
}
3. Категории сообщений
| Категория | Префикс ключа | Пример использования |
|---|---|---|
| Errors | errors.* |
Сообщения об ошибках, исключения |
| Info | info.* |
Информационные сообщения |
| Warnings | warnings.* |
Предупреждения |
| Prompts | prompts.* |
Запросы к пользователю |
| Status | status.* |
Статусы операций |
| Choices | choices.* |
Варианты выбора |
Формат JSON каталога
{
"version": "1.0.0",
"language": "ru",
"fallback": "en",
"messages": {
"errors.admin_required": "Запустите этот скрипт из сеанса PowerShell с правами администратора.",
"errors.binary_missing": "Отсутствует требуемый двоичный файл ActivityWatch: {0}",
"info.starting_deployment": "Начало развертывания ActivityWatch версии {0}...",
"prompts.confirm_install": "Вы уверены, что хотите установить ActivityWatch для {0} пользователей?"
}
}
Поля каталога
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
version |
string | Да | Семантическая версия (X.Y.Z) |
language |
string | Да | Код языка (например, "ru", "en") |
fallback |
string/null | Да | Код резервного языка или null |
messages |
object | Да | Объект с сообщениями |
Скрипты управления
Валидация переводов
Проверяет структуру JSON, наличие обязательных полей, консистентность плейсхолдеров:
cd i18n
npm install
npm run validate
Анализ покрытия
Сравнивает все локали с reference (en-US) и показывает процент покрытия:
npm run coverage
Пример вывода:
┌──────────────────────────────────────────────────────────────────────────────┐
│ Locale │ Version │ Language │ Coverage │ Missing │ Extra │
├──────────────────────────────────────────────────────────────────────────────┤
│ ru-RU │ 1.0.0 │ ru │ 100.00% ✅ │ 0 │ 0 │
└──────────────────────────────────────────────────────────────────────────────┘
Автоверсионирование
Бump версии всех каталогов одновременно:
# Patch bump (1.0.0 → 1.0.1)
npm run bump
# Minor bump (1.0.0 → 1.1.0)
npm run bump -- --minor
# Major bump (1.0.0 → 2.0.0)
npm run bump -- --major
Интеграция с существующими скриптами
Обновление ActivityWatch.Windows.Common.psm1
Замените хардкодные строки на вызовы i18n:
До:
throw 'Run this script from an elevated PowerShell session.'
После:
throw (Get-LocalizedString -Key "errors.admin_required")
Обновление deploy-ensemble.ps1
До:
Write-Host "Starting ActivityWatch deployment..." -ForegroundColor Cyan
После:
Get-LocalizedInfo -Key "starting_deployment"
Добавление нового языка
-
Скопируйте
en-US.jsonкак шаблон:cp i18n/en-US.json i18n/fr-FR.json -
Отредактируйте
fr-FR.json:- Измените
languageна"fr" - Установите
fallbackв"en" - Переведите все сообщения в
messages
- Измените
-
Проверьте валидность:
npm run validate fr-FR.json -
Протестируйте в PowerShell:
Initialize-Locale -Culture "fr-FR"
Best Practices
✅ Делайте
- Используйте семантическое версионирование для каталогов
- Всегда указывайте fallback для resilience
- Группируйте сообщения по категориям (errors., info., etc.)
- Нумеруйте плейсхолдеры последовательно:
{0},{1},{2} - Проверяйте покрытие перед релизом (
npm run coverage)
❌ Не делайте
- Не хардкодьте строки в коде скриптов
- Не смешивайте языки в одном сообщении
- Не пропускайте плейсхолдеры в переводах
- Не забывайте обновлять версию при изменении сообщений
Troubleshooting
Ошибка: "Localization file not found"
Убедитесь, что путь к i18n директории правильный:
$env:I18N_ROOT = "C:\Path\To\i18n"
Initialize-Locale -Culture "ru-RU" -I18nRoot $env:I18N_ROOT
Ошибка: "Failed to format message"
Проверьте соответствие количества аргументов плейсхолдерам:
# ❌ Неправильно: 2 аргумента для 1 плейсхолдера
Get-LocalizedString -Key "errors.binary_missing" -FormatArgs @("file.exe", "extra")
# ✅ Правильно
Get-LocalizedString -Key "errors.binary_missing" -FormatArgs @("file.exe")
Missing keys после обновления en-US
Запустите анализ покрытия и добавьте отсутствующие ключи:
npm run coverage
# Отредактируйте ru-RU.json, добавив missing keys
npm run validate
Миграция с хардкодных строк
-
Экспортируйте существующие строки в шаблон:
Export-LocaleTemplate -OutputPath ".\i18n\template.json" -
Заполните переводы
-
Постепенно заменяйте строки в коде на вызовы i18n функций
-
Протестируйте с обоими локалями
Лицензия
MIT