mirror of
https://github.com/fish-shell/fish-shell.git
synced 2026-04-21 17:21:14 -03:00
This is done in preparation for Fluent's FTL files, which will be placed in `localization/fluent/`. Having a shared parent reduces top-level clutter in the repo and makes it easier to find the localization files for translators, including realizing that both PO and FTL files exist. We keep PO and FTL files in separate directories because we need to rebuild on any changes in the PO directory (technically only when there are changes to `*.po` files, but due to technical limitations we can't reliably trigger rebuilds only if those changes but not other files in the same directory.) Changes to FTL files do not require rebuilds for dev builds, since for these `rust-embed` does not actually embed them into the binary but rather loads them from the file system at runtime. Closes #12193
157 lines
5.6 KiB
Fish
Executable File
157 lines
5.6 KiB
Fish
Executable File
#!/usr/bin/env fish
|
|
|
|
# Updates the files used for gettext translations.
|
|
# By default, the whole xgettext + msgmerge pipeline runs,
|
|
# which extracts the messages from the source files into $template_file,
|
|
# and updates the PO files for each language from that.
|
|
#
|
|
# Use cases:
|
|
# For developers:
|
|
# - Run with no args to update all PO files after making changes to Rust/fish sources.
|
|
# For translators:
|
|
# - Specify the language you want to work on as an argument, which must be a file in the
|
|
# localization/po/ directory. You can specify a language which does not have translations
|
|
# yet by specifying the name of a file which does not yet exist.
|
|
# Make sure to follow the naming convention.
|
|
# For testing:
|
|
# - Specify `--dry-run` to see if any updates to the PO files would by applied by this script.
|
|
# If this flag is specified, the script will exit with an error if there are outstanding
|
|
# changes, and will display the diff. Do not specify other flags if `--dry-run` is specified.
|
|
#
|
|
# Specify `--use-existing-template=DIR` to prevent running cargo for extracting an up-to-date
|
|
# version of the localized strings. This flag is intended for testing setups which make it
|
|
# inconvenient to run cargo here, but run it in an earlier step to ensure up-to-date values.
|
|
# This argument is passed on to the `fish_xgettext.fish` script and has no other uses.
|
|
# `DIR` must be the path to a gettext template file generated from our compilation process.
|
|
# It can be obtained by running:
|
|
# set -l DIR (mktemp -d)
|
|
# FISH_GETTEXT_EXTRACTION_DIR=$DIR cargo check --features=gettext-extract
|
|
|
|
# The sort utility is locale-sensitive.
|
|
# Ensure that sorting output is consistent by setting LC_ALL here.
|
|
set -gx LC_ALL C.UTF-8
|
|
|
|
set -l build_tools (status dirname)
|
|
set -l po_dir $build_tools/../localization/po
|
|
|
|
set -l extract
|
|
|
|
argparse dry-run use-existing-template= -- $argv
|
|
or exit $status
|
|
|
|
if test -z $argv[1]
|
|
# Update everything if not specified otherwise.
|
|
set -g po_files $po_dir/*.po
|
|
else
|
|
set -l po_dir_id (stat --format='%d:%i' -- $po_dir)
|
|
for arg in $argv
|
|
set -l arg_dir_id (stat --format='%d:%i' -- (dirname $arg) 2>/dev/null)
|
|
if test $po_dir_id != "$arg_dir_id"
|
|
echo "Argument $arg is not a file in the directory $(realpath $po_dir)."
|
|
echo "Non-option arguments must specify paths to files in this directory."
|
|
echo ""
|
|
echo "If you want to add a new language to the translations not the following:"
|
|
echo "The filename must identify a language, with a two letter ISO 639-1 language code of the target language (e.g. 'pt' for Portuguese), and use the file extension '.po'."
|
|
echo "Optionally, you can specify a regional variant (e.g. 'pt_BR')."
|
|
echo "So valid filenames are of the shape 'll.po' or 'll_CC.po'."
|
|
exit 1
|
|
end
|
|
if not basename $arg | grep -qE '^[a-z]{2,3}(_[A-Z]{2})?\.po$'
|
|
echo "Filename does not match the expected format ('ll.po' or 'll_CC.po')."
|
|
exit 1
|
|
end
|
|
end
|
|
set -g po_files $argv
|
|
end
|
|
|
|
set -g template_file (mktemp)
|
|
# Protect from externally set $tmpdir leaking into this script.
|
|
set -g tmpdir
|
|
|
|
function cleanup_exit
|
|
set -l exit_status $status
|
|
|
|
rm $template_file
|
|
|
|
if set -g --query tmpdir[1]
|
|
rm -r $tmpdir
|
|
end
|
|
|
|
exit $exit_status
|
|
end
|
|
|
|
if set -l --query extract
|
|
set -l xgettext_args
|
|
if set -l --query _flag_use_existing_template
|
|
set xgettext_args --use-existing-template=$_flag_use_existing_template
|
|
end
|
|
$build_tools/fish_xgettext.fish $xgettext_args >$template_file
|
|
or cleanup_exit
|
|
end
|
|
|
|
if set -l --query _flag_dry_run
|
|
# On a dry run, we do not modify localization/po/ but write to a temporary directory instead
|
|
# and check if there is a difference between localization/po/ and the tmpdir after re-generating
|
|
# the PO files.
|
|
set -g tmpdir (mktemp -d)
|
|
|
|
# Ensure tmpdir has the same initial state as the po dir.
|
|
cp -r $po_dir/* $tmpdir
|
|
end
|
|
|
|
# This is used to identify lines which should be set here via $header_lines.
|
|
# Make sure that this prefix does not appear elsewhere in the file and only contains characters
|
|
# without special meaning in a sed pattern.
|
|
set -g header_prefix "# fish-note-sections: "
|
|
|
|
function print_header
|
|
set -l header_lines \
|
|
"Translations are divided into sections, each starting with a fish-section-* pseudo-message." \
|
|
"The first few sections are more important." \
|
|
"Ignore the tier3 sections unless you have a lot of time."
|
|
for line in $header_lines
|
|
printf '%s%s\n' $header_prefix $line
|
|
end
|
|
end
|
|
|
|
function merge_po_files --argument-names template_file po_file
|
|
msgmerge --no-wrap --update --no-fuzzy-matching --backup=none --quiet \
|
|
$po_file $template_file
|
|
or cleanup_exit
|
|
set -l new_po_file (mktemp) # TODO Remove on failure.
|
|
# Remove obsolete messages instead of keeping them as #~ entries.
|
|
and msgattrib --no-wrap --no-obsolete -o $new_po_file $po_file
|
|
or cleanup_exit
|
|
|
|
begin
|
|
print_header
|
|
# Paste PO file without old header lines.
|
|
sed '/^'$header_prefix'/d' $new_po_file
|
|
end >$po_file
|
|
rm $new_po_file
|
|
end
|
|
|
|
for po_file in $po_files
|
|
if set --query tmpdir[1]
|
|
set po_file $tmpdir/(basename $po_file)
|
|
end
|
|
if test -e $po_file
|
|
merge_po_files $template_file $po_file
|
|
else
|
|
begin
|
|
print_header
|
|
cat $template_file
|
|
end >$po_file
|
|
end
|
|
end
|
|
|
|
if set -g --query tmpdir[1]
|
|
diff -ur $po_dir $tmpdir
|
|
or begin
|
|
echo ERROR: translations in localization/po/ are stale. Try running build_tools/update_translations.fish
|
|
cleanup_exit
|
|
end
|
|
end
|
|
|
|
cleanup_exit
|