diff options
author | Jussi Pakkanen <jpakkane@gmail.com> | 2022-01-22 01:01:29 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-01-22 01:01:29 +0200 |
commit | 4316b71017e1f4ca0d3d65f675e6cdceb3330d97 (patch) | |
tree | 69070743b7a206aaa11947f31cfec70762f3de97 /mesonbuild | |
parent | 2a992526045b702a8ab72968c98fef9f9e189d2b (diff) | |
parent | 02fb0c3f8bb60d88998c8a8c7d090ecc864ed04c (diff) | |
download | meson-4316b71017e1f4ca0d3d65f675e6cdceb3330d97.zip meson-4316b71017e1f4ca0d3d65f675e6cdceb3330d97.tar.gz meson-4316b71017e1f4ca0d3d65f675e6cdceb3330d97.tar.bz2 |
Merge pull request #9742 from ximion/wip/itstool
i18n: Add support for joining XML localization via itstool
Diffstat (limited to 'mesonbuild')
-rw-r--r-- | mesonbuild/modules/i18n.py | 81 | ||||
-rw-r--r-- | mesonbuild/scripts/itstool.py | 82 |
2 files changed, 162 insertions, 1 deletions
diff --git a/mesonbuild/modules/i18n.py b/mesonbuild/modules/i18n.py index 5be7eb0..d92e334 100644 --- a/mesonbuild/modules/i18n.py +++ b/mesonbuild/modules/i18n.py @@ -59,6 +59,20 @@ if T.TYPE_CHECKING: languages: T.List[str] preset: T.Optional[str] + class ItsJoinFile(TypedDict): + + input: T.List[T.Union[ + str, build.BuildTarget, build.CustomTarget, build.CustomTargetIndex, + build.ExtractedObjects, build.GeneratedList, ExternalProgram, + mesonlib.File]] + output: T.List[str] + build_by_default: bool + install: bool + install_dir: T.List[T.Union[str, bool]] + install_tag: T.List[str] + its_files: T.List[str] + mo_targets: T.List[T.Union[build.BuildTarget, build.CustomTarget, build.CustomTargetIndex]] + _ARGS: KwargInfo[T.List[str]] = KwargInfo( 'args', @@ -115,6 +129,7 @@ class I18nModule(ExtensionModule): self.methods.update({ 'merge_file': self.merge_file, 'gettext': self.gettext, + 'itstool_join': self.itstool_join, }) @staticmethod @@ -122,6 +137,10 @@ class I18nModule(ExtensionModule): mlog.warning('Gettext not found, all translation targets will be ignored.', once=True) @staticmethod + def noitstool_error() -> T.NoReturn: + raise mesonlib.MesonException('Did not find itstool. Please install it to continue.') + + @staticmethod def _get_data_dirs(state: 'ModuleState', dirs: T.Iterable[str]) -> T.List[str]: """Returns source directories of relative paths""" src_dir = path.join(state.environment.get_source_dir(), state.subdir) @@ -184,7 +203,7 @@ class I18nModule(ExtensionModule): return ModuleReturnValue(ct, [ct]) - @typed_pos_args('i81n.gettex', str) + @typed_pos_args('i81n.gettext', str) @typed_kwargs( 'i18n.gettext', _ARGS, @@ -269,5 +288,65 @@ class I18nModule(ExtensionModule): return ModuleReturnValue([gmotargets, pottarget, updatepotarget], targets) + @FeatureNew('i18n.itstool_join', '0.61.0') + @noPosargs + @typed_kwargs( + 'i18n.itstool_join', + CT_BUILD_BY_DEFAULT, + CT_INPUT_KW, + CT_INSTALL_DIR_KW, + CT_INSTALL_TAG_KW, + CT_OUTPUT_KW, + INSTALL_KW, + _ARGS.evolve(), + KwargInfo('its_files', ContainerTypeInfo(list, str)), + KwargInfo('mo_targets', ContainerTypeInfo(list, build.CustomTarget), required=True), + ) + def itstool_join(self, state: 'ModuleState', args: T.List['TYPE_var'], kwargs: 'ItsJoinFile') -> ModuleReturnValue: + if not shutil.which('itstool'): + self.noitstool_error() + mo_targets = kwargs['mo_targets'] + its_files = kwargs.get('its_files', []) + + mo_fnames = [] + for target in mo_targets: + mo_fnames.append(path.join(target.get_subdir(), target.get_outputs()[0])) + + command: T.List[T.Union[str, build.BuildTarget, build.CustomTarget, + build.CustomTargetIndex, 'ExternalProgram', mesonlib.File]] = [] + command.extend(state.environment.get_build_command()) + command.extend([ + '--internal', 'itstool', 'join', + '-i', '@INPUT@', + '-o', '@OUTPUT@' + ]) + if its_files: + for fname in its_files: + if not path.isabs(fname): + fname = path.join(state.environment.source_dir, state.subdir, fname) + command.extend(['--its', fname]) + command.extend(mo_fnames) + + build_by_default = kwargs['build_by_default'] + if build_by_default is None: + build_by_default = kwargs['install'] + + real_kwargs = { + 'build_by_default': build_by_default, + 'command': command, + 'depends': mo_targets, + 'install': kwargs['install'], + 'install_dir': kwargs['install_dir'], + 'output': kwargs['output'], + 'input': kwargs['input'], + 'install_tag': kwargs['install_tag'], + } + + ct = build.CustomTarget('', state.subdir, state.subproject, + T.cast(T.Dict[str, T.Any], real_kwargs)) + + return ModuleReturnValue(ct, [ct]) + + def initialize(interp: 'Interpreter') -> I18nModule: return I18nModule(interp) diff --git a/mesonbuild/scripts/itstool.py b/mesonbuild/scripts/itstool.py new file mode 100644 index 0000000..fa3b0fa --- /dev/null +++ b/mesonbuild/scripts/itstool.py @@ -0,0 +1,82 @@ +# Copyright 2016 The Meson development team + +# 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. + +import os +import argparse +import subprocess +import tempfile +import shutil +import typing as T + +parser = argparse.ArgumentParser() +parser.add_argument('command') +parser.add_argument('--build-dir', default='') +parser.add_argument('-i', '--input', default='') +parser.add_argument('-o', '--output', default='') +parser.add_argument('--its', action='append', default=[]) +parser.add_argument('mo_files', nargs='+') + + +def run_join(build_dir: str, its_files: T.List[str], mo_files: T.List[str], in_fname: str, out_fname: str) -> int: + if not mo_files: + print('No mo files specified to use for translation.') + return 1 + + with tempfile.TemporaryDirectory(prefix=os.path.basename(in_fname), dir=build_dir) as tmp_dir: + # copy mo files to have the right names so itstool can infer their locale + locale_mo_files = [] + for mo_file in mo_files: + if not os.path.exists(mo_file): + print('Could not find mo file {}'.format(mo_file)) + return 1 + if not mo_file.endswith('.mo'): + print('File is not a mo file: {}'.format(mo_file)) + return 1 + # determine locale of this mo file + parts = mo_file.partition('LC_MESSAGES') + if parts[0].endswith((os.sep, '/')): + locale = os.path.basename(parts[0][:-1]) + else: + locale = os.path.basename(parts[0]) + tmp_mo_fname = os.path.join(tmp_dir, locale + '.mo') + shutil.copy(mo_file, tmp_mo_fname) + locale_mo_files.append(tmp_mo_fname) + + cmd = ['itstool'] + if its_files: + for fname in its_files: + cmd.extend(['-i', fname]) + cmd.extend(['-j', in_fname, + '-o', out_fname]) + cmd.extend(locale_mo_files) + + return subprocess.call(cmd) + + +def run(args: T.List[str]) -> int: + options = parser.parse_args(args) + command = options.command + build_dir = os.environ.get('MESON_BUILD_ROOT', os.getcwd()) + if options.build_dir: + build_dir = options.build_dir + + if command == 'join': + return run_join(build_dir, + options.its, + options.mo_files, + options.input, + options.output) + else: + print('Unknown subcommand.') + return 1 |