Check dub version (#11794)
* DubDependency._check_dub returns the version * check for compatible Dub version Dub versions starting at 1.32 have a new cache structure into which Meson doesn't know where to find compatible artifacts * skipping D tests involving Dub * refactor _check_dub makes mypy happier * make linters happy * localize some logic
This commit is contained in:
parent
9d64143a4f
commit
d5ae94f571
|
@ -15,7 +15,7 @@ from __future__ import annotations
|
||||||
|
|
||||||
from .base import ExternalDependency, DependencyException, DependencyTypeName
|
from .base import ExternalDependency, DependencyException, DependencyTypeName
|
||||||
from .pkgconfig import PkgConfigDependency
|
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 ..programs import ExternalProgram
|
||||||
from .. import mlog
|
from .. import mlog
|
||||||
import re
|
import re
|
||||||
|
@ -26,8 +26,11 @@ import typing as T
|
||||||
if T.TYPE_CHECKING:
|
if T.TYPE_CHECKING:
|
||||||
from ..environment import Environment
|
from ..environment import Environment
|
||||||
|
|
||||||
|
|
||||||
class DubDependency(ExternalDependency):
|
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]):
|
def __init__(self, name: str, environment: 'Environment', kwargs: T.Dict[str, T.Any]):
|
||||||
super().__init__(DependencyTypeName('dub'), environment, kwargs, language='d')
|
super().__init__(DependencyTypeName('dub'), environment, kwargs, language='d')
|
||||||
|
@ -41,19 +44,27 @@ class DubDependency(ExternalDependency):
|
||||||
if 'required' in kwargs:
|
if 'required' in kwargs:
|
||||||
self.required = kwargs.get('required')
|
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:
|
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:
|
if self.required:
|
||||||
raise DependencyException('DUB not found.')
|
raise DependencyException('DUB not found.')
|
||||||
self.is_found = False
|
self.is_found = False
|
||||||
return
|
return
|
||||||
|
|
||||||
|
(self.dubbin, dubver) = DubDependency.class_dubbin
|
||||||
|
|
||||||
assert isinstance(self.dubbin, ExternalProgram)
|
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 '
|
mlog.debug('Determining dependency {!r} with DUB executable '
|
||||||
'{!r}'.format(name, self.dubbin.get_path()))
|
'{!r}'.format(name, self.dubbin.get_path()))
|
||||||
|
|
||||||
|
@ -125,13 +136,16 @@ class DubDependency(ExternalDependency):
|
||||||
elif 'compiler' not in compatibilities:
|
elif 'compiler' not in compatibilities:
|
||||||
mlog.error(mlog.bold(pack_id), 'found but not compiled with ', mlog.bold(dub_comp_id))
|
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:
|
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:
|
elif 'arch' not in compatibilities:
|
||||||
mlog.error(mlog.bold(pack_id), 'found but not compiled for', mlog.bold(dub_arch))
|
mlog.error(mlog.bold(pack_id), 'found but not compiled for', mlog.bold(dub_arch))
|
||||||
elif 'platform' not in compatibilities:
|
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:
|
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:
|
else:
|
||||||
mlog.error(mlog.bold(pack_id), 'not found')
|
mlog.error(mlog.bold(pack_id), 'not found')
|
||||||
|
|
||||||
|
@ -168,7 +182,7 @@ class DubDependency(ExternalDependency):
|
||||||
self.is_found = False
|
self.is_found = False
|
||||||
return
|
return
|
||||||
|
|
||||||
## check that the main dependency is indeed a library
|
# check that the main dependency is indeed a library
|
||||||
if pkg['name'] == name:
|
if pkg['name'] == name:
|
||||||
self.is_found = True
|
self.is_found = True
|
||||||
|
|
||||||
|
@ -322,7 +336,8 @@ class DubDependency(ExternalDependency):
|
||||||
|
|
||||||
if d_ver_reg is not None:
|
if d_ver_reg is not None:
|
||||||
frontend_version = d_ver_reg.group()
|
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])
|
comp_versions.extend([frontend_version, frontend_id])
|
||||||
|
|
||||||
compatibilities: T.Set[str] = set()
|
compatibilities: T.Set[str] = set()
|
||||||
|
@ -380,25 +395,40 @@ class DubDependency(ExternalDependency):
|
||||||
p, out, err = Popen_safe(self.compiler.get_exelist() + args, env=env)
|
p, out, err = Popen_safe(self.compiler.get_exelist() + args, env=env)
|
||||||
return p.returncode, out.strip(), err.strip()
|
return p.returncode, out.strip(), err.strip()
|
||||||
|
|
||||||
def _check_dub(self) -> T.Union[bool, ExternalProgram]:
|
def _check_dub(self) -> T.Optional[T.Tuple[ExternalProgram, str]]:
|
||||||
dubbin: T.Union[bool, ExternalProgram] = ExternalProgram('dub', silent=True)
|
|
||||||
assert isinstance(dubbin, ExternalProgram)
|
def find() -> T.Optional[T.Tuple[ExternalProgram, str]]:
|
||||||
if dubbin.found():
|
dubbin = ExternalProgram('dub', silent=True)
|
||||||
|
|
||||||
|
if not dubbin.found():
|
||||||
|
return None
|
||||||
|
|
||||||
try:
|
try:
|
||||||
p, out = Popen_safe(dubbin.get_command() + ['--version'])[0:2]
|
p, out = Popen_safe(dubbin.get_command() + ['--version'])[0:2]
|
||||||
if p.returncode != 0:
|
if p.returncode != 0:
|
||||||
mlog.warning('Found dub {!r} but couldn\'t run it'
|
mlog.warning('Found dub {!r} but couldn\'t run it'
|
||||||
''.format(' '.join(dubbin.get_command())))
|
''.format(' '.join(dubbin.get_command())))
|
||||||
# Set to False instead of None to signify that we've already
|
return None
|
||||||
# searched for it and not found it
|
|
||||||
dubbin = False
|
|
||||||
except (FileNotFoundError, PermissionError):
|
except (FileNotFoundError, PermissionError):
|
||||||
dubbin = False
|
return None
|
||||||
else:
|
|
||||||
dubbin = False
|
vermatch = re.search(r'DUB version (\d+\.\d+\.\d+.*), ', out.strip())
|
||||||
if isinstance(dubbin, ExternalProgram):
|
if vermatch:
|
||||||
mlog.log('Found DUB:', mlog.bold(dubbin.get_path()),
|
dubver = vermatch.group(1)
|
||||||
'(%s)' % out.strip())
|
|
||||||
else:
|
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'))
|
mlog.log('Found DUB:', mlog.red('NO'))
|
||||||
return dubbin
|
else:
|
||||||
|
(dubbin, dubver) = found
|
||||||
|
mlog.log('Found DUB:', mlog.bold(dubbin.get_path()),
|
||||||
|
'(version %s)' % dubver)
|
||||||
|
|
||||||
|
return found
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
project('dub-example', 'd')
|
project('dub-example', 'd')
|
||||||
|
|
||||||
|
error('MESON_SKIP_TEST: Dub support is broken at the moment (#11773)')
|
||||||
|
|
||||||
dub_exe = find_program('dub', required : false)
|
dub_exe = find_program('dub', required : false)
|
||||||
if not dub_exe.found()
|
if not dub_exe.found()
|
||||||
error('MESON_SKIP_TEST: Dub not found')
|
error('MESON_SKIP_TEST: Dub not found')
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
project('dub-with-deps-example', ['d'])
|
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)
|
dub_exe = find_program('dub', required : false)
|
||||||
if not dub_exe.found()
|
if not dub_exe.found()
|
||||||
error('MESON_SKIP_TEST: Dub not found')
|
error('MESON_SKIP_TEST: Dub not found')
|
||||||
|
|
Loading…
Reference in New Issue