diff options
Diffstat (limited to 'mesonbuild')
-rw-r--r-- | mesonbuild/modules/dlang.py | 74 |
1 files changed, 51 insertions, 23 deletions
diff --git a/mesonbuild/modules/dlang.py b/mesonbuild/modules/dlang.py index 966b070..35ce86b 100644 --- a/mesonbuild/modules/dlang.py +++ b/mesonbuild/modules/dlang.py @@ -7,27 +7,45 @@ from __future__ import annotations import json import os +import typing as T + from . import ExtensionModule, ModuleInfo from .. import mlog +from ..build import InvalidArguments from ..dependencies import Dependency from ..dependencies.dub import DubDependency from ..interpreterbase import typed_pos_args from ..mesonlib import Popen_safe, MesonException, listify +if T.TYPE_CHECKING: + from typing_extensions import Literal, TypeAlias + + from . import ModuleState + from ..build import OverrideExecutable + from ..interpreter.interpreter import Interpreter + from ..interpreterbase.baseobjects import TYPE_kwargs + from ..programs import ExternalProgram, OverrideProgram + + _AnyProgram: TypeAlias = T.Union[OverrideExecutable, ExternalProgram, OverrideProgram] + _JSONTypes: TypeAlias = T.Union[str, int, bool, None, T.List['_JSONTypes'], T.Dict[str, '_JSONTypes']] + + class DlangModule(ExtensionModule): - class_dubbin = None + class_dubbin: T.Union[_AnyProgram, Literal[False], None] = None init_dub = False + dubbin: T.Union[_AnyProgram, Literal[False], None] + INFO = ModuleInfo('dlang', '0.48.0') - def __init__(self, interpreter): + def __init__(self, interpreter: Interpreter): super().__init__(interpreter) self.methods.update({ 'generate_dub_file': self.generate_dub_file, }) - def _init_dub(self, state): + def _init_dub(self, state: ModuleState) -> None: if DlangModule.class_dubbin is None and DubDependency.class_dubbin is not None: self.dubbin = DubDependency.class_dubbin[0] DlangModule.class_dubbin = self.dubbin @@ -45,11 +63,11 @@ class DlangModule(ExtensionModule): raise MesonException('DUB not found.') @typed_pos_args('dlang.generate_dub_file', str, str) - def generate_dub_file(self, state, args, kwargs): + def generate_dub_file(self, state: ModuleState, args: T.Tuple[str, str], kwargs: TYPE_kwargs) -> None: if not DlangModule.init_dub: self._init_dub(state) - config = { + config: T.Dict[str, _JSONTypes] = { 'name': args[0] } @@ -70,7 +88,7 @@ class DlangModule(ExtensionModule): for key, value in kwargs.items(): if key == 'dependencies': values = listify(value, flatten=False) - config[key] = {} + data: T.Dict[str, _JSONTypes] = {} for dep in values: if isinstance(dep, Dependency): name = dep.get_name() @@ -78,20 +96,33 @@ class DlangModule(ExtensionModule): if ret == 0: version = dep.get_version() if version is None: - config[key][name] = '' + data[name] = '' else: - config[key][name] = version + data[name] = version + config[key] = data else: - config[key] = value + def _do_validate(v: object) -> _JSONTypes: + if not isinstance(v, (str, int, bool, list, dict)): + raise InvalidArguments('keyword arguments must be strings, numbers, booleans, arrays, or dictionaries of such') + if isinstance(v, list): + for e in v: + _do_validate(e) + if isinstance(v, dict): + for e in v.values(): + _do_validate(e) + return T.cast('_JSONTypes', v) + + config[key] = _do_validate(value) with open(config_path, 'w', encoding='utf-8') as ofile: ofile.write(json.dumps(config, indent=4, ensure_ascii=False)) - def _call_dubbin(self, args, env=None): + def _call_dubbin(self, args: T.List[str], env: T.Optional[T.Mapping[str, str]] = None) -> T.Tuple[int, str]: + assert self.dubbin is not None and self.dubbin is not False, 'for mypy' p, out = Popen_safe(self.dubbin.get_command() + args, env=env)[0:2] return p.returncode, out.strip() - def check_dub(self, state): + def check_dub(self, state: ModuleState) -> T.Union[_AnyProgram, Literal[False]]: dubbin = state.find_program('dub', silent=True) if dubbin.found(): try: @@ -101,17 +132,14 @@ class DlangModule(ExtensionModule): ''.format(' '.join(dubbin.get_command()))) # Set to False instead of None to signify that we've already # searched for it and not found it - dubbin = False + else: + mlog.log('Found DUB:', mlog.green('YES'), ':', mlog.bold(dubbin.get_path() or ''), + '({})'.format(out.strip())) + return dubbin except (FileNotFoundError, PermissionError): - dubbin = False - else: - dubbin = False - if dubbin: - mlog.log('Found DUB:', mlog.bold(dubbin.get_path()), - '(%s)' % out.strip()) - else: - mlog.log('Found DUB:', mlog.red('NO')) - return dubbin + pass + mlog.log('Found DUB:', mlog.red('NO')) + return False -def initialize(*args, **kwargs): - return DlangModule(*args, **kwargs) +def initialize(interp: Interpreter) -> DlangModule: + return DlangModule(interp) |