From c88a1dc55c58830b0e23feb29a1be49a3eade571 Mon Sep 17 00:00:00 2001 From: Eli Schwartz Date: Tue, 22 Mar 2022 21:53:45 -0400 Subject: [PATCH] fix bug in i18n merge_file/itstool_join revealed by previous commit Logically, i18n.merge_file cannot ever take a MULTI_OUTPUT_KW, but it does take a CT_OUTPUT_KW-like interface. Actually trying to pass multiple merge_file outputs causes the msgfmthelper script to be entirely malformed in the arguments it accepts, and treat the broken one like a --flag, then exit with argparse errors. Even if we somehow assumed that somehow it was designed to actually allow this, msgfmt doesn't support conceptually passing multiple outputs so that would be a msgfmt error instead of an error inside the guts of `meson --internal msgfmthelper`. Same logic applies again for the itstool command and the itstool internal helper. Catch this error at configuration time by using the single-output kwarg form. Likewise, it's totally nonsense to accept multiple install_dir or install_tags, and ever since commit 11f96380351a88059ec55f1070fdebc1b1033117 the CustomTarget itself won't even check this. --- docs/markdown/i18n-module.md | 6 +++++ mesonbuild/modules/i18n.py | 44 ++++++++++++++++++++---------------- 2 files changed, 31 insertions(+), 19 deletions(-) diff --git a/docs/markdown/i18n-module.md b/docs/markdown/i18n-module.md index 13c64f809..dc4186aec 100644 --- a/docs/markdown/i18n-module.md +++ b/docs/markdown/i18n-module.md @@ -49,6 +49,9 @@ This merges translations into a text file using `msgfmt`. See [[@custom_tgt]] for normal keywords. In addition it accepts these keywords: +* `output`: same as `custom_target` but only accepts one item +* `install_dir`: same as `custom_target` but only accepts one item +* `install_tag`: same as `custom_target` but only accepts one item * `data_dirs`: (*Added 0.41.0*) list of directories for its files (See also `i18n.gettext()`) * `po_dir`: directory containing translations, relative to current directory @@ -63,6 +66,9 @@ This joins translations into a XML file using `itstool`. See [[@custom_tgt]] for normal keywords. In addition it accepts these keywords: +* `output`: same as `custom_target` but only accepts one item +* `install_dir`: same as `custom_target` but only accepts one item +* `install_tag`: same as `custom_target` but only accepts one item * `its_files`: filenames of ITS files that should be used explicitly (XML translation rules are autodetected otherwise). * `mo_targets` *required*: mo file generation targets as returned by `i18n.gettext()`. diff --git a/mesonbuild/modules/i18n.py b/mesonbuild/modules/i18n.py index 4ea5772dd..5fd31716c 100644 --- a/mesonbuild/modules/i18n.py +++ b/mesonbuild/modules/i18n.py @@ -20,7 +20,7 @@ from . import ExtensionModule, ModuleReturnValue from .. import build from .. import mesonlib from .. import mlog -from ..interpreter.type_checking import CT_BUILD_BY_DEFAULT, CT_INPUT_KW, CT_INSTALL_DIR_KW, CT_INSTALL_TAG_KW, MULTI_OUTPUT_KW, INSTALL_KW, NoneType, in_set_validator +from ..interpreter.type_checking import CT_BUILD_BY_DEFAULT, CT_INPUT_KW, INSTALL_TAG_KW, OUTPUT_KW, INSTALL_KW, NoneType, in_set_validator from ..interpreterbase import FeatureNew from ..interpreterbase.decorators import ContainerTypeInfo, KwargInfo, noPosargs, typed_kwargs, typed_pos_args from ..scripts.gettext import read_linguas @@ -41,11 +41,11 @@ if T.TYPE_CHECKING: str, build.BuildTarget, build.CustomTarget, build.CustomTargetIndex, build.ExtractedObjects, build.GeneratedList, ExternalProgram, mesonlib.File]] - output: T.List[str] + output: str build_by_default: bool install: bool - install_dir: T.List[T.Union[str, bool]] - install_tag: T.List[str] + install_dir: T.Optional[str] + install_tag: T.Optional[str] args: T.List[str] data_dirs: T.List[str] po_dir: str @@ -66,11 +66,11 @@ if T.TYPE_CHECKING: str, build.BuildTarget, build.CustomTarget, build.CustomTargetIndex, build.ExtractedObjects, build.GeneratedList, ExternalProgram, mesonlib.File]] - output: T.List[str] + output: str build_by_default: bool install: bool - install_dir: T.List[T.Union[str, bool]] - install_tag: T.List[str] + install_dir: T.Optional[str] + install_tag: T.Optional[str] its_files: T.List[str] mo_targets: T.List[T.Union[build.BuildTarget, build.CustomTarget, build.CustomTargetIndex]] @@ -152,9 +152,9 @@ class I18nModule(ExtensionModule): 'i18n.merge_file', CT_BUILD_BY_DEFAULT, CT_INPUT_KW, - CT_INSTALL_DIR_KW, - CT_INSTALL_TAG_KW, - MULTI_OUTPUT_KW, + KwargInfo('install_dir', (str, NoneType)), + INSTALL_TAG_KW, + OUTPUT_KW, INSTALL_KW, _ARGS.evolve(since='0.51.0'), _DATA_DIRS.evolve(since='0.41.0'), @@ -187,6 +187,9 @@ class I18nModule(ExtensionModule): if build_by_default is None: build_by_default = kwargs['install'] + install_dir = [kwargs['install_dir']] if kwargs['install_dir'] is not None else None + install_tag = [kwargs['install_tag']] if kwargs['install_tag'] is not None else None + ct = build.CustomTarget( '', state.subdir, @@ -194,11 +197,11 @@ class I18nModule(ExtensionModule): state.environment, command, kwargs['input'], - kwargs['output'], + [kwargs['output']], build_by_default=build_by_default, install=kwargs['install'], - install_dir=kwargs['install_dir'], - install_tag=kwargs['install_tag'], + install_dir=install_dir, + install_tag=install_tag, ) return ModuleReturnValue(ct, [ct]) @@ -321,9 +324,9 @@ class I18nModule(ExtensionModule): 'i18n.itstool_join', CT_BUILD_BY_DEFAULT, CT_INPUT_KW, - CT_INSTALL_DIR_KW, - CT_INSTALL_TAG_KW, - MULTI_OUTPUT_KW, + KwargInfo('install_dir', (str, NoneType)), + INSTALL_TAG_KW, + OUTPUT_KW, INSTALL_KW, _ARGS.evolve(), KwargInfo('its_files', ContainerTypeInfo(list, str)), @@ -359,6 +362,9 @@ class I18nModule(ExtensionModule): if build_by_default is None: build_by_default = kwargs['install'] + install_dir = [kwargs['install_dir']] if kwargs['install_dir'] is not None else None + install_tag = [kwargs['install_tag']] if kwargs['install_tag'] is not None else None + ct = build.CustomTarget( '', state.subdir, @@ -366,12 +372,12 @@ class I18nModule(ExtensionModule): state.environment, command, kwargs['input'], - kwargs['output'], + [kwargs['output']], build_by_default=build_by_default, extra_depends=mo_targets, install=kwargs['install'], - install_dir=kwargs['install_dir'], - install_tag=kwargs['install_tag'], + install_dir=install_dir, + install_tag=install_tag, ) return ModuleReturnValue(ct, [ct])