Commit be26836f authored by Brendan Burns's avatar Brendan Burns Committed by Brendan Burns

Update extraction script, sort messages, add .pot file.

parent 17375fc5
#!/bin/bash
# Copyright 2017 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
KUBECTL_FILES="pkg/kubectl/cmd/*.go pkg/kubectl/cmd/*/*.go"
generate_pot="false"
generate_mo="false"
while getopts "hf:xg" opt; do
case $opt in
h)
echo "$0 [-f files] [-x] [-g]"
echo " -f <file-path>: Files to process"
echo " -x extract strings to a POT file"
echo " -g sort .po files and generate .mo files"
exit 0
;;
f)
KUBECTL_FILES="${OPTARG}"
;;
x)
generate_pot="true"
;;
g)
generate_mo="true"
;;
\?)
echo "[-f <files>] -x -g" >&2
exit 1
;;
esac
done
if ! which go-xgettext > /dev/null; then
echo 'Can not find go-xgettext, install with:'
echo 'go get github.com/gosexy/gettext/go-xgettext'
exit 1
fi
if ! which msgfmt > /dev/null; then
echo 'Can not find msgfmt, install with:'
echo 'apt-get install gettext'
exit 1
fi
if [[ "${generate_pot}" == "true" ]]; then
echo "Extracting strings to POT"
go-xgettext -k=i18n.T ${KUBECTL_FILES} > tmp.pot
msgcat -s tmp.pot > translations/kubectl/template.pot
rm tmp.pot
fi
if [[ "${generate_mo}" == "true" ]]; then
echo "Generating .po and .mo files"
for x in translations/*/*/*/*.po; do
msgcat -s $x > tmp.po
mv tmp.po $x
echo "generating .mo file for: $x"
msgfmt $x -o "$(dirname $x)/$(basename $x .po).mo"
done
fi
./hack/generate-bindata.sh
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -120,9 +120,9 @@ func LoadTranslations(root string, getLanguageFn func() string) error { ...@@ -120,9 +120,9 @@ func LoadTranslations(root string, getLanguageFn func() string) error {
// and plural translation is used. // and plural translation is used.
func T(defaultValue string, args ...int) string { func T(defaultValue string, args ...int) string {
if len(args) == 0 { if len(args) == 0 {
return gettext.PGettext(defaultValue, defaultValue) return gettext.PGettext("", defaultValue)
} }
return fmt.Sprintf(gettext.PNGettext(defaultValue, defaultValue, defaultValue+".plural", args[0]), return fmt.Sprintf(gettext.PNGettext("", defaultValue, defaultValue+".plural", args[0]),
args[0]) args[0])
} }
......
...@@ -10,16 +10,35 @@ no need to update `translations/test/...` which is only used for unit tests. ...@@ -10,16 +10,35 @@ no need to update `translations/test/...` which is only used for unit tests.
There is an example [PR here](https://github.com/kubernetes/kubernetes/pull/40645) which adds support for French. There is an example [PR here](https://github.com/kubernetes/kubernetes/pull/40645) which adds support for French.
Move on to Adding new translations Once you've added a new language, you'll need to register it in
`pkg/util/i18n/i18n.go` by adding it to the `knownTranslations` map.
## Wrapping strings
There is a simple script in `translations/extract.py` that performs
simple regular expression based wrapping of strings. It can always
use improvements to understand additional strings.
## Extracting strings
Once the strings are wrapped, you can extract strings from go files using
the `go-xgettext` command which can be installed with:
```console
go get github.com/gosexy/gettext/tree/master/go-xgettext
```
Once that's installed you can run `hack/update-translations.sh`, which
will extract and sort any new strings.
## Adding new translations ## Adding new translations
Edit the appropriate `k8s.po` file, `poedit` is a popular open source tool Edit the appropriate `k8s.po` file, `poedit` is a popular open source tool
for translations. for translations. You can load the `translations/kubectl/template.pot` file
to find messages that might be missing.
Once you are done with your `.po` file, generate the corresponding `k8s.mo` Once you are done with your `.po` file, generate the corresponding `k8s.mo`
file. `poedit` does this automatically on save. file. `poedit` does this automatically on save, but you can also use
`hack/update-translations.sh` to perform the `po` to `mo` translation.
We use the English translation as both the `msg_id` and the `msg_context`. We use the English translation as the `msgid`.
## Regenerating the bindata file ## Regenerating the bindata file
Run `./hack/generate-bindata.sh, this will turn the translation files Run `./hack/generate-bindata.sh, this will turn the translation files
......
...@@ -34,14 +34,10 @@ class MatchHandler(object): ...@@ -34,14 +34,10 @@ class MatchHandler(object):
self.regex = re.compile(regex) self.regex = re.compile(regex)
self.replace_fn = replace_fn self.replace_fn = replace_fn
# global holding all strings discovered
STRINGS = []
def short_replace(match, file, line_number): def short_replace(match, file, line_number):
"""Replace a Short: ... cobra command description with an internationalization """Replace a Short: ... cobra command description with an internationalization
""" """
sys.stdout.write('{}i18n.T({}),\n'.format(match.group(1), match.group(2))) sys.stdout.write('{}i18n.T({}),\n'.format(match.group(1), match.group(2)))
STRINGS.append((match.group(2), file, line_number))
SHORT_MATCH = MatchHandler(r'(\s+Short:\s+)("[^"]+"),', short_replace) SHORT_MATCH = MatchHandler(r'(\s+Short:\s+)("[^"]+"),', short_replace)
...@@ -54,6 +50,14 @@ def import_replace(match, file, line_number): ...@@ -54,6 +50,14 @@ def import_replace(match, file, line_number):
IMPORT_MATCH = MatchHandler('(.*"k8s.io/kubernetes/pkg/kubectl/cmd/util")', import_replace) IMPORT_MATCH = MatchHandler('(.*"k8s.io/kubernetes/pkg/kubectl/cmd/util")', import_replace)
def string_flag_replace(match, file, line_number):
"""Replace a cmd.Flags().String("...", "", "...") with an internationalization
"""
sys.stdout.write('{}i18n.T("{})"))\n'.format(match.group(1), match.group(2)))
STRING_FLAG_MATCH = MatchHandler('(\s+cmd\.Flags\(\).String\("[^"]*", "[^"]*", )"([^"]*)"\)', string_flag_replace)
def replace(filename, matchers): def replace(filename, matchers):
"""Given a file and a set of matchers, run those matchers """Given a file and a set of matchers, run those matchers
across the file and replace it with the results. across the file and replace it with the results.
...@@ -75,22 +79,6 @@ def replace(filename, matchers): ...@@ -75,22 +79,6 @@ def replace(filename, matchers):
# gofmt the file again # gofmt the file again
from subprocess import call from subprocess import call
call(["gofmt", "-s", "-w", filename]) call(["goimports", "-w", filename])
# update the translation files
translation_files = [
"translations/kubectl/default/LC_MESSAGES/k8s.po",
"translations/kubectl/en_US/LC_MESSAGES/k8s.po",
]
for translation_filename in translation_files:
with open(translation_filename, "a") as tfile:
for translation_string in STRINGS:
msg_string = translation_string[0]
tfile.write('\n')
tfile.write('# https://github.com/kubernetes/kubernetes/blob/master/{}#L{}\n'.format(translation_string[1], translation_string[2]))
tfile.write('msgctxt {}\n'.format(msg_string))
tfile.write('msgid {}\n'.format(msg_string))
tfile.write('msgstr {}\n'.format(msg_string))
replace(sys.argv[1], [SHORT_MATCH, IMPORT_MATCH]) replace(sys.argv[1], [SHORT_MATCH, IMPORT_MATCH, STRING_FLAG_MATCH])
...@@ -19,96 +19,78 @@ msgstr "" ...@@ -19,96 +19,78 @@ msgstr ""
"Plural-Forms: nplurals=2; plural=(n > 1);\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n"
"Language: fr\n" "Language: fr\n"
msgctxt "Update the annotations on a resource"
msgid "Update the annotations on a resource"
msgstr "Mettre à jour les annotations d'une ressource"
msgctxt ""
"watch is only supported on individual resources and resource collections - "
"%d resources were found"
msgid ""
"watch is only supported on individual resources and resource collections - "
"%d resources were found"
msgid_plural ""
"watch is only supported on individual resources and resource collections - "
"%d resources were found"
msgstr[0] ""
"watch n'est compatible qu'avec les ressources individuelles et les "
"collections de ressources. - %d ressource a été trouvée. "
msgstr[1] ""
"watch n'est compatible qu'avec les ressources individuelles et les "
"collections de ressources. - %d ressources ont été trouvées. "
# https://github.com/kubernetes/kubernetes/blob/masterpkg/kubectl/cmd/apply.go#L98 # https://github.com/kubernetes/kubernetes/blob/masterpkg/kubectl/cmd/apply.go#L98
msgctxt "Apply a configuration to a resource by filename or stdin"
msgid "Apply a configuration to a resource by filename or stdin" msgid "Apply a configuration to a resource by filename or stdin"
msgstr "" msgstr ""
"Appliquer une configuration à une ressource par nom de fichier ou depuis " "Appliquer une configuration à une ressource par nom de fichier ou depuis "
"stdin" "stdin"
# https://github.com/kubernetes/kubernetes/blob/master/pkg/kubectl/cmd/config/config.go#L39
msgctxt "Modify kubeconfig files"
msgid "Modify kubeconfig files"
msgstr "Modifier des fichiers kubeconfig"
# https://github.com/kubernetes/kubernetes/blob/master/pkg/kubectl/cmd/config/create_authinfo.go#L103
msgctxt "Sets a user entry in kubeconfig"
msgid "Sets a user entry in kubeconfig"
msgstr "Définit un utilisateur dans kubeconfig"
# https://github.com/kubernetes/kubernetes/blob/master/pkg/kubectl/cmd/config/create_cluster.go#L67
msgctxt "Sets a cluster entry in kubeconfig"
msgid "Sets a cluster entry in kubeconfig"
msgstr "Définit un cluster dans kubeconfig"
# https://github.com/kubernetes/kubernetes/blob/master/pkg/kubectl/cmd/config/create_context.go#L57
msgctxt "Sets a context entry in kubeconfig"
msgid "Sets a context entry in kubeconfig"
msgstr "Définit un contexte dans kubeconfig"
# https://github.com/kubernetes/kubernetes/blob/master/pkg/kubectl/cmd/config/current_context.go#L48
msgctxt "Displays the current-context"
msgid "Displays the current-context"
msgstr "Affiche le contexte actuel"
# https://github.com/kubernetes/kubernetes/blob/master/pkg/kubectl/cmd/config/delete_cluster.go#L38 # https://github.com/kubernetes/kubernetes/blob/master/pkg/kubectl/cmd/config/delete_cluster.go#L38
msgctxt "Delete the specified cluster from the kubeconfig"
msgid "Delete the specified cluster from the kubeconfig" msgid "Delete the specified cluster from the kubeconfig"
msgstr "Supprimer le cluster spécifié du kubeconfig" msgstr "Supprimer le cluster spécifié du kubeconfig"
# https://github.com/kubernetes/kubernetes/blob/master/pkg/kubectl/cmd/config/delete_context.go#L38 # https://github.com/kubernetes/kubernetes/blob/master/pkg/kubectl/cmd/config/delete_context.go#L38
msgctxt "Delete the specified context from the kubeconfig"
msgid "Delete the specified context from the kubeconfig" msgid "Delete the specified context from the kubeconfig"
msgstr "Supprimer le contexte spécifié du kubeconfig" msgstr "Supprimer le contexte spécifié du kubeconfig"
# https://github.com/kubernetes/kubernetes/blob/master/pkg/kubectl/cmd/config/get_contexts.go#L62
msgid "Describe one or many contexts"
msgstr "Décrire un ou plusieurs contextes"
# https://github.com/kubernetes/kubernetes/blob/master/pkg/kubectl/cmd/config/get_clusters.go#L40 # https://github.com/kubernetes/kubernetes/blob/master/pkg/kubectl/cmd/config/get_clusters.go#L40
msgctxt "Display clusters defined in the kubeconfig"
msgid "Display clusters defined in the kubeconfig" msgid "Display clusters defined in the kubeconfig"
msgstr "Afficher les cluster définis dans kubeconfig" msgstr "Afficher les cluster définis dans kubeconfig"
# https://github.com/kubernetes/kubernetes/blob/master/pkg/kubectl/cmd/config/get_contexts.go#L62 # https://github.com/kubernetes/kubernetes/blob/master/pkg/kubectl/cmd/config/view.go#L64
msgctxt "Describe one or many contexts" msgid "Display merged kubeconfig settings or a specified kubeconfig file"
msgid "Describe one or many contexts" msgstr ""
msgstr "Décrire un ou plusieurs contextes" "Afficher les paramètres fusionnés de kubeconfig ou d'un fichier kubeconfig "
"spécifié"
# https://github.com/kubernetes/kubernetes/blob/master/pkg/kubectl/cmd/config/current_context.go#L48
msgid "Displays the current-context"
msgstr "Affiche le contexte actuel"
# https://github.com/kubernetes/kubernetes/blob/master/pkg/kubectl/cmd/config/config.go#L39
msgid "Modify kubeconfig files"
msgstr "Modifier des fichiers kubeconfig"
# https://github.com/kubernetes/kubernetes/blob/master/pkg/kubectl/cmd/config/create_cluster.go#L67
msgid "Sets a cluster entry in kubeconfig"
msgstr "Définit un cluster dans kubeconfig"
# https://github.com/kubernetes/kubernetes/blob/master/pkg/kubectl/cmd/config/create_context.go#L57
msgid "Sets a context entry in kubeconfig"
msgstr "Définit un contexte dans kubeconfig"
# https://github.com/kubernetes/kubernetes/blob/master/pkg/kubectl/cmd/config/create_authinfo.go#L103
msgid "Sets a user entry in kubeconfig"
msgstr "Définit un utilisateur dans kubeconfig"
# https://github.com/kubernetes/kubernetes/blob/master/pkg/kubectl/cmd/config/set.go#L59 # https://github.com/kubernetes/kubernetes/blob/master/pkg/kubectl/cmd/config/set.go#L59
msgctxt "Sets an individual value in a kubeconfig file"
msgid "Sets an individual value in a kubeconfig file" msgid "Sets an individual value in a kubeconfig file"
msgstr "Définit une valeur individuelle dans un fichier kubeconfig" msgstr "Définit une valeur individuelle dans un fichier kubeconfig"
# https://github.com/kubernetes/kubernetes/blob/master/pkg/kubectl/cmd/config/use_context.go#L48
msgid "Sets the current-context in a kubeconfig file"
msgstr "Définit le contexte courant dans un fichier kubeconfig"
# https://github.com/kubernetes/kubernetes/blob/master/pkg/kubectl/cmd/config/unset.go#L47 # https://github.com/kubernetes/kubernetes/blob/master/pkg/kubectl/cmd/config/unset.go#L47
msgctxt "Unsets an individual value in a kubeconfig file"
msgid "Unsets an individual value in a kubeconfig file" msgid "Unsets an individual value in a kubeconfig file"
msgstr "Supprime une valeur individuelle dans un fichier kubeconfig" msgstr "Supprime une valeur individuelle dans un fichier kubeconfig"
# https://github.com/kubernetes/kubernetes/blob/master/pkg/kubectl/cmd/config/use_context.go#L48 msgid "Update the annotations on a resource"
msgctxt "Sets the current-context in a kubeconfig file" msgstr "Mettre à jour les annotations d'une ressource"
msgid "Sets the current-context in a kubeconfig file"
msgstr "Définit le contexte courant dans un fichier kubeconfig"
# https://github.com/kubernetes/kubernetes/blob/master/pkg/kubectl/cmd/config/view.go#L64 msgid ""
msgctxt "Display merged kubeconfig settings or a specified kubeconfig file" "watch is only supported on individual resources and resource collections - "
msgid "Display merged kubeconfig settings or a specified kubeconfig file" "%d resources were found"
msgstr "" msgid_plural ""
"Afficher les paramètres fusionnés de kubeconfig ou d'un fichier kubeconfig " "watch is only supported on individual resources and resource collections - "
"spécifié" "%d resources were found"
msgstr[0] ""
"watch n'est compatible qu'avec les ressources individuelles et les "
"collections de ressources. - %d ressource a été trouvée. "
msgstr[1] ""
"watch n'est compatible qu'avec les ressources individuelles et les "
"collections de ressources. - %d ressources ont été trouvées. "
...@@ -19,12 +19,10 @@ msgstr "" ...@@ -19,12 +19,10 @@ msgstr ""
"Plural-Forms: nplurals=2; plural=(n != 1);\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n"
"Language: en\n" "Language: en\n"
msgctxt "test_string"
msgid "test_string"
msgstr "foo"
msgctxt "test_plural"
msgid "test_plural" msgid "test_plural"
msgid_plural "test_plural" msgid_plural "test_plural"
msgstr[0] "there was %d item" msgstr[0] "there was %d item"
msgstr[1] "there were %d items" msgstr[1] "there were %d items"
msgid "test_string"
msgstr "foo"
...@@ -19,12 +19,10 @@ msgstr "" ...@@ -19,12 +19,10 @@ msgstr ""
"Plural-Forms: nplurals=2; plural=(n != 1);\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n"
"Language: en\n" "Language: en\n"
msgctxt "test_string"
msgid "test_string"
msgstr "baz"
msgctxt "test_plural"
msgid "test_plural" msgid "test_plural"
msgid_plural "test_plural" msgid_plural "test_plural"
msgstr[0] "there was %d item" msgstr[0] "there was %d item"
msgstr[1] "there were %d items" msgstr[1] "there were %d items"
msgid "test_string"
msgstr "baz"
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment