Refresh Lazarus Translations with updatepofiles
Add a string to a Lazarus form and the translations quietly go stale: updatepofiles is the tool that catches your .pot and .po files back up. This guide uses the Lazarus 3.0 build from lcl-utils-3.0, package version 3.0+dfsg1-8build3.
The route
Jump straight to the step you need, or tick off Done means at the end.
Allow about fifteen minutes for a small project. You need a shell, a project translation directory, at least one .pot file, and the relevant Lazarus resource files. This changes translation files, so back up or use version control first. No elevated privilege is normally required.
1. Check which updatepofiles you are running
The unversioned command is an alternatives-managed link on this machine. Confirm it resolves to Lazarus 3.0 and record the package version:
$ command -v updatepofiles
/usr/bin/updatepofiles
$ readlink -f "$(command -v updatepofiles)"
/usr/lib/lazarus/3.0/tools/updatepofiles
$ dpkg-query -W -f='${Package} ${Version}\n' lcl-utils-3.0
lcl-utils-3.0 3.0+dfsg1-8build3
- Use the versioned name in scripts.
updatepofiles-3.0pins the release; the alternatives link can change later. - Trust the binary over the man page. The local manual is older: it describes
.poarguments and claims there are no options.
Checkpoint
Ask the installed binary for its usage text:
$ updatepofiles
Usage: updatepofiles [--searchdir=<dir>] [filenameA.rsj [filenameB.rsj ... filenameN.rsj]] filename1.pot [filename2.pot ... filenameN.pot]
Do not treat --help or --version as supported options here: this build reads them as filenames and prints an invalid-extension message.
2. Make a recoverable copy
Run this from the directory containing your translation files, or point the paths at your project directory:
$ cd /path/to/project/translations
$ cp -a . "backup-before-updatepofiles-$(date +%Y%m%d-%H%M%S)"
$ find . -maxdepth 1 -type f \( -name '*.pot' -o -name '*.po' \) -print | sort
The command can touch the .pot file and its translated .po companions. If the files are tracked, a clean working tree is an equally good recovery point, but do not run this against a production checkout without checking what the diff will contain first.
3. Update a POT file from resource strings
A resource file goes before the catalogue it belongs to. The installed tool accepts .rsj, plus the older .rst and .lrj extensions:
$ updatepofiles \
/path/to/build/lib/messages.rsj \
/path/to/project/translations/project.pot
You can repeat the pair for separate projects in one call:
$ updatepofiles \
/path/to/build/app.rsj /path/to/app/translations/app.pot \
/path/to/build/tools.rsj /path/to/tools/translations/tools.pot
There is normally no success message, so verify the catalogue changed as expected:
$ git diff -- project.pot
$ rg -n '^msgid ' project.pot | tail
Warning
Do not assume every resource string belongs in every catalogue. Pair each resource file with the correct .pot, and inspect the diff for stray messages before committing it.
4. Let the tool find resource files
Use --searchdir=<dir> when a resource filename is not in the current directory. The search covers that directory and its subdirectories:
$ updatepofiles \
--searchdir=/path/to/build \
messages.rsj \
/path/to/project/translations/project.pot
Current resource string table file search directory: "/path/to/build"
Give the resource basename, not a guessed path. If the file cannot be found, the command reports an error and the catalogue is not a reliable result, so check the exact name first:
$ find /path/to/build -type f -name 'messages.rsj' -print
/path/to/build/lcl/messages.rsj
Checkpoint
If find prints nothing, stop and fix the build output or the search directory. Do not create an empty resource file just to satisfy the command.
5. Merge the translated PO files
Once the .pot is updated, updatepofiles also merges new messages into translated files matching the catalogue's project name, such as project.fr.po or project.de.po. A run with only the catalogue is enough:
$ updatepofiles /path/to/project/translations/project.pot
$ git diff --stat -- /path/to/project/translations
$ git diff -- /path/to/project/translations/project.pot \
/path/to/project/translations/project.*.po
New entries should show as untranslated messages in the language files. Existing translations are data, not proof a message is still correct: review changed, fuzzy or empty entries with your normal translation workflow.
Warning
Do not grant root access merely because a file is unwritable. If the project directory belongs to another account, resolve ownership with its administrator instead. Running the updater as root can leave the whole checkout owned by root and makes recovery harder.
6. Recover from an unwanted update
Before committing, discard only the files you deliberately inspected. For a Git checkout, restore the catalogue and language files from the last commit:
$ git restore -- project.pot project.fr.po project.de.po
$ git status --short
Recovery
If you used the timestamped backup instead, copy the required files back after comparing them. Do not use a broad recursive delete or restore command when the directory contains unrelated work. Then rerun the updater with the corrected resource-to-catalogue pairing and inspect the diff again.
Done means
- Command resolves correctly. It points at the Lazarus release you intended.
- Pairing checked. Resource files and
.potfiles were paired deliberately. - Diff reviewed. The generated diff contains only expected catalogue and translation changes.
- Messages available. New strings are ready for translators.
- Update is recoverable. It is backed up or committed so it can be undone.