Проверка импорта XLIFF в Xcode на облачном Mac

Проверка импорта XLIFF в Xcode на облачном Mac

Когда версия приближается к этапу заморозки, поставщик локализации обычно возвращает один или несколько файлов .xcloc или .xliff. Импортировать их двойным щелчком прямо в повседневную рабочую копию разработчика кажется быстрым решением, но вместе с переводами в проект могут попасть устаревшие ключи, неверно указанные целевые языки и повреждённые заполнители. Надёжнее создать на облачном Mac одноразовый каталог для проверки: экспортировать эталон из текущего коммита, выполнить предварительную проверку полученных файлов, а затем импортировать их, изучить различия и запустить сборку.

Зафиксируйте среду проверки

Узел проверки должен начинать работу с чистого коммита. Не используйте повторно рабочую копию, в которую уже импортировалась локализация, и не проводите проверку в каталоге с незакоммиченными изменениями. Для каждой поставки можно создать временную ветку или отдельный worktree:

git fetch origin
git worktree add ../localization-review origin/main
cd ../localization-review
git switch -c review/localization-batch
xcodebuild -version
git status --short

Запишите в журнал вывод xcodebuild -version, SHA коммита, целевую Scheme и идентификатор партии перевода. Если команда использует несколько версий Xcode, явно задайте DEVELOPER_DIR, чтобы интерактивный терминал и автоматические задания не запускали разные наборы инструментов.

export DEVELOPER_DIR="/Applications/Xcode.app/Contents/Developer"
xcode-select -p
git rev-parse HEAD

Критерий успешной проверки локализации — не просто возможность открыть файл, а получение объяснимого результата для одного и того же коммита, одной и той же версии инструментов Xcode и одного набора параметров экспорта.

При выполнении проверки на облачном Mac от GPUMini сначала просмотрите в консоли доступные конфигурации, а затем выберите подходящий узел. Для этой задачи обычно не требуется высокая степень параллелизма, однако при полной сборке крупного проекта после импорта необходимо учитывать доступный объём памяти и свободное место на диске.

Экспортируйте эталон из текущего проекта

Для .xcodeproj используйте параметр проекта. Если проект работает через Workspace, замените его на -workspace и укажите общую Scheme. В следующем примере экспортируются упрощённый китайский, японский и французский языки. Чтобы добавить другие языки, повторите параметр -exportLanguage:

mkdir -p Artifacts/Baseline
xcodebuild \
  -project ExampleApp.xcodeproj \
  -scheme ExampleApp \
  -exportLocalizations \
  -localizationPath Artifacts/Baseline \
  -exportLanguage zh-Hans \
  -exportLanguage ja \
  -exportLanguage fr

После завершения экспорта сначала сохраните список файлов, не перезаписывая сразу полученные переводы:

find Artifacts/Baseline -type f -print0 \
  | sort -z \
  | xargs -0 shasum -a 256 > Artifacts/baseline.sha256

Эталон отвечает на три вопроса: какие единицы текущего проекта доступны для перевода, как выглядит их содержимое на исходном языке и какие целевые языки распознаёт Xcode. Если в полученных файлах есть ключи, отсутствующие в эталоне, перевод, скорее всего, был подготовлен на основе старого коммита. Если же в эталоне появилось много новых непереведённых единиц, в поставку могли не войти недавно добавленные функции.

Проверьте структуру XLIFF и заполнители до импорта

XLIFF представляет собой XML. Сначала проверьте корректность формата системными средствами, а затем извлеките языковые атрибуты и количество единиц перевода. Не изменяйте XML с помощью регулярных выражений. На этапе предварительной проверки файлы можно читать, но исправления следует вносить в средстве локализации или с помощью прошедшего ревью сценария.

find Incoming -name "*.xliff" -print0 |
while IFS= read -r -d '' file; do
  echo "Checking $file"
  xmllint --noout "$file"
  xmllint --xpath \
    'string(/*[local-name()="xliff"]/*[local-name()="file"][1]/@target-language)' \
    "$file"
  echo
done

Ошибки в заполнителях — важнейшая причина блокировать импорт. %@, %d, позиционные параметры и переменные, созданные String Catalog, должны сохранять смысловое соответствие между исходным и целевым текстом. Простого подсчёта знаков процента недостаточно: %%, ширина поля и позиционные параметры имеют разное значение. Рекомендуется с помощью XML-парсера отдельно прочитать source и target каждого trans-unit, нормализовать заполнители и сравнить полученные мультимножества.

Проверка Условие блокировки Действие
Структура XML xmllint возвращает ненулевой код Вернуть полученный файл
Целевой язык Не соответствует партии перевода Исправить сопоставление языков и повторить экспорт
Единицы перевода Обнаружены неизвестные ID Проверить коммит эталона
Заполнители Не совпадают типы или количество Исправить перевод и повторить проверку
Пустой перевод Целевой текст важного элемента интерфейса пуст Уточнить, разрешён ли откат к исходному тексту

В строках форматирования, видимых пользователю, также выборочно проверяйте переносы строк, управляющие последовательности и ветви множественного числа. Порядок заполнителей может меняться в зависимости от языка, но при использовании позиционных параметров их индексы должны оставаться допустимыми.

Импортируйте в изолированном каталоге и проверьте различия

После успешной предварительной проверки импортируйте пакеты .xcloc по одному. Сразу после каждого импорта фиксируйте состояние репозитория, чтобы можно было определить, какой именно файл привёл к отклонениям:

mkdir -p Artifacts/Logs
for package in Incoming/*.xcloc; do
  name="$(basename "$package" .xcloc)"
  xcodebuild \
    -project ExampleApp.xcodeproj \
    -importLocalizations \
    -localizationPath "$package" \
    2>&1 | tee "Artifacts/Logs/import-${name}.log"
  test "${PIPESTATUS[0]}" -eq 0 || exit 1
  git status --short
done

Успешный импорт ещё не означает завершения проверки. Сначала оцените масштаб изменений с помощью git diff --stat, а затем изучите различия по каждому файлу. Ожидаемые изменения должны быть сосредоточены в String Catalog, строковых ресурсах или каталогах соответствующих языков. Если изменились Scheme, параметры сборки, настройки подписи или посторонние файлы проекта, остановите процесс и выясните причину.

git diff --stat
git diff --check
git diff -- '*.xcstrings' '*.strings' '*.stringsdict' 'project.pbxproj'

Команда git diff --check позволяет обнаружить некоторые замыкающие пробелы и следы конфликтов, но не оценивает смысл перевода. Рекомендуется сформировать сводку добавленных, удалённых и изменённых единиц перевода и сохранить её как артефакт конвейера вместе с журналами импорта.

Завершите цикл сборкой и повторным экспортом

В завершение выполните чистую сборку целевой Scheme. Если проект содержит несколько целевых приложений или расширений, проверка должна охватывать реальный путь выпуска, а не только минимальную библиотечную цель.

set -o pipefail
xcodebuild \
  -project ExampleApp.xcodeproj \
  -scheme ExampleApp \
  -configuration Release \
  -destination 'generic/platform=iOS Simulator' \
  clean build |
  tee Artifacts/Logs/localization-build.log

После успешной сборки снова экспортируйте XLIFF из проекта с импортированными переводами и сравните результат с эталоном. Повторный экспорт помогает обнаружить переводы, которые фактически не попали в проект, ошибки сопоставления языковых кодов и единицы, оставшиеся непереведёнными после импорта. При сравнении игнорируйте изменения, связанные только с сортировкой или созданными инструментами метаданными. Анализируйте исходный и целевой текст, статус и примечания каждой единицы перевода.

Поддерживаемый конвейер проверки должен сохранять четыре категории подтверждающих данных: сведения о наборе инструментов и коммите, отчёты предварительной проверки, сводку различий после импорта и журналы сборки. При сбое не очищайте рабочий каталог автоматически — сначала сохраните его состояние для анализа. После успешной проверки удалите временный worktree, чтобы следующая поставка не унаследовала прежнее состояние.

Итоговые условия допуска можно сформулировать так: XML корректно разбирается, целевой язык указан верно, наборы заполнителей совпадают, неизвестные единицы перевода отсутствуют, область изменений соответствует ожиданиям, а целевая Scheme успешно собирается. В таком процессе облачный Mac становится воспроизводимым узлом проверки локализации, а не ещё одной средой импорта, состояние которой приходится поддерживать по памяти вручную.

Часто задаваемые вопросы

Зачем перед проверкой перевода экспортировать свежий XLIFF?

Свежий экспорт фиксирует набор строк, исходный текст и языки текущей версии проекта, поэтому устаревшие и неизвестные единицы перевода сразу заметны.

Достаточно ли успешного импорта XLIFF для выпуска?

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

Можно ли импортировать перевод прямо в основную рабочую копию?

Лучше использовать временную ветку или отдельное рабочее дерево, сохранить журнал импорта и переносить только проверенные изменения ресурсов.

Выделенный физический узел

Как выбрать облачный Mac для разработки и сборки

Сравните две конфигурации M4, четыре срока аренды и четыре доступных узла, а затем выполните развертывание под задачи проекта.

Выбрать конфигурацию и заказать