diff options
-rw-r--r-- | mesonbuild/dependencies/dub.py | 86 | ||||
-rw-r--r-- | test cases/d/11 dub/meson.build | 2 | ||||
-rw-r--r-- | test cases/d/14 dub with deps/meson.build | 2 |
3 files changed, 62 insertions, 28 deletions
diff --git a/mesonbuild/dependencies/dub.py b/mesonbuild/dependencies/dub.py index ac2b667..37a9ea1 100644 --- a/mesonbuild/dependencies/dub.py +++ b/mesonbuild/dependencies/dub.py @@ -15,7 +15,7 @@ from __future__ import annotations from .base import ExternalDependency, DependencyException, DependencyTypeName from .pkgconfig import PkgConfigDependency -from ..mesonlib import (Popen_safe, OptionKey, join_args) +from ..mesonlib import (Popen_safe, OptionKey, join_args, version_compare) from ..programs import ExternalProgram from .. import mlog import re @@ -26,8 +26,11 @@ import typing as T if T.TYPE_CHECKING: from ..environment import Environment + class DubDependency(ExternalDependency): - class_dubbin = None + # dub program and version + class_dubbin: T.Optional[T.Tuple[ExternalProgram, str]] = None + class_dubbin_searched = False def __init__(self, name: str, environment: 'Environment', kwargs: T.Dict[str, T.Any]): super().__init__(DependencyTypeName('dub'), environment, kwargs, language='d') @@ -41,19 +44,27 @@ class DubDependency(ExternalDependency): if 'required' in kwargs: self.required = kwargs.get('required') + if DubDependency.class_dubbin is None and not DubDependency.class_dubbin_searched: + DubDependency.class_dubbin = self._check_dub() + DubDependency.class_dubbin_searched = True if DubDependency.class_dubbin is None: - self.dubbin = self._check_dub() - DubDependency.class_dubbin = self.dubbin - else: - self.dubbin = DubDependency.class_dubbin - - if not self.dubbin: if self.required: raise DependencyException('DUB not found.') self.is_found = False return + (self.dubbin, dubver) = DubDependency.class_dubbin + assert isinstance(self.dubbin, ExternalProgram) + + # Check if Dub version is compatible with Meson + if version_compare(dubver, '>1.31.1'): + if self.required: + raise DependencyException( + f"DUB version {dubver} is not compatible with Meson (can't locate artifacts in Dub cache)") + self.is_found = False + return + mlog.debug('Determining dependency {!r} with DUB executable ' '{!r}'.format(name, self.dubbin.get_path())) @@ -125,13 +136,16 @@ class DubDependency(ExternalDependency): elif 'compiler' not in compatibilities: mlog.error(mlog.bold(pack_id), 'found but not compiled with ', mlog.bold(dub_comp_id)) elif dub_comp_id != 'gdc' and 'compiler_version' not in compatibilities: - mlog.error(mlog.bold(pack_id), 'found but not compiled with', mlog.bold(f'{dub_comp_id}-{self.compiler.version}')) + mlog.error(mlog.bold(pack_id), 'found but not compiled with', + mlog.bold(f'{dub_comp_id}-{self.compiler.version}')) elif 'arch' not in compatibilities: mlog.error(mlog.bold(pack_id), 'found but not compiled for', mlog.bold(dub_arch)) elif 'platform' not in compatibilities: - mlog.error(mlog.bold(pack_id), 'found but not compiled for', mlog.bold(description['platform'].join('.'))) + mlog.error(mlog.bold(pack_id), 'found but not compiled for', + mlog.bold(description['platform'].join('.'))) elif 'configuration' not in compatibilities: - mlog.error(mlog.bold(pack_id), 'found but not compiled for the', mlog.bold(pkg['configuration']), 'configuration') + mlog.error(mlog.bold(pack_id), 'found but not compiled for the', + mlog.bold(pkg['configuration']), 'configuration') else: mlog.error(mlog.bold(pack_id), 'not found') @@ -168,7 +182,7 @@ class DubDependency(ExternalDependency): self.is_found = False return - ## check that the main dependency is indeed a library + # check that the main dependency is indeed a library if pkg['name'] == name: self.is_found = True @@ -318,11 +332,12 @@ class DubDependency(ExternalDependency): if ret != 0: mlog.error('Failed to run {!r}', mlog.bold(dub_comp_id)) return (None, None) - d_ver_reg = re.search('v[0-9].[0-9][0-9][0-9].[0-9]', res) # Ex.: v2.081.2 + d_ver_reg = re.search('v[0-9].[0-9][0-9][0-9].[0-9]', res) # Ex.: v2.081.2 if d_ver_reg is not None: frontend_version = d_ver_reg.group() - frontend_id = frontend_version.rsplit('.', 1)[0].replace('v', '').replace('.', '') # Fix structure. Ex.: 2081 + frontend_id = frontend_version.rsplit('.', 1)[0].replace( + 'v', '').replace('.', '') # Fix structure. Ex.: 2081 comp_versions.extend([frontend_version, frontend_id]) compatibilities: T.Set[str] = set() @@ -380,25 +395,40 @@ class DubDependency(ExternalDependency): p, out, err = Popen_safe(self.compiler.get_exelist() + args, env=env) return p.returncode, out.strip(), err.strip() - def _check_dub(self) -> T.Union[bool, ExternalProgram]: - dubbin: T.Union[bool, ExternalProgram] = ExternalProgram('dub', silent=True) - assert isinstance(dubbin, ExternalProgram) - if dubbin.found(): + def _check_dub(self) -> T.Optional[T.Tuple[ExternalProgram, str]]: + + def find() -> T.Optional[T.Tuple[ExternalProgram, str]]: + dubbin = ExternalProgram('dub', silent=True) + + if not dubbin.found(): + return None + try: p, out = Popen_safe(dubbin.get_command() + ['--version'])[0:2] if p.returncode != 0: mlog.warning('Found dub {!r} but couldn\'t run it' ''.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 + return None + except (FileNotFoundError, PermissionError): - dubbin = False + return None + + vermatch = re.search(r'DUB version (\d+\.\d+\.\d+.*), ', out.strip()) + if vermatch: + dubver = vermatch.group(1) + else: + mlog.warning(f"Found dub {' '.join(dubbin.get_command())} but couldn't parse version in {out.strip()}") + return None + + return (dubbin, dubver) + + found = find() + + if found is None: + mlog.log('Found DUB:', mlog.red('NO')) else: - dubbin = False - if isinstance(dubbin, ExternalProgram): + (dubbin, dubver) = found mlog.log('Found DUB:', mlog.bold(dubbin.get_path()), - '(%s)' % out.strip()) - else: - mlog.log('Found DUB:', mlog.red('NO')) - return dubbin + '(version %s)' % dubver) + + return found diff --git a/test cases/d/11 dub/meson.build b/test cases/d/11 dub/meson.build index d852ca0..3bb3d56 100644 --- a/test cases/d/11 dub/meson.build +++ b/test cases/d/11 dub/meson.build @@ -1,5 +1,7 @@ project('dub-example', 'd') +error('MESON_SKIP_TEST: Dub support is broken at the moment (#11773)') + dub_exe = find_program('dub', required : false) if not dub_exe.found() error('MESON_SKIP_TEST: Dub not found') diff --git a/test cases/d/14 dub with deps/meson.build b/test cases/d/14 dub with deps/meson.build index 08f3080..c8e472b 100644 --- a/test cases/d/14 dub with deps/meson.build +++ b/test cases/d/14 dub with deps/meson.build @@ -1,5 +1,7 @@ project('dub-with-deps-example', ['d']) +error('MESON_SKIP_TEST: Dub support is broken at the moment (#11773)') + dub_exe = find_program('dub', required : false) if not dub_exe.found() error('MESON_SKIP_TEST: Dub not found') |