aboutsummaryrefslogtreecommitdiff
path: root/mesonbuild
diff options
context:
space:
mode:
authorRemi Thebault <remi.thebault@gmail.com>2023-05-18 14:50:35 +0200
committerGitHub <noreply@github.com>2023-05-18 15:50:35 +0300
commitd5ae94f571af17ec969a4320b54e322f77d6e725 (patch)
tree49c70e1fb89eeea1d1b4757574b13e7781397c90 /mesonbuild
parent9d64143a4f7cf36c052c679a1411f60ccff2fa7e (diff)
downloadmeson-d5ae94f571af17ec969a4320b54e322f77d6e725.zip
meson-d5ae94f571af17ec969a4320b54e322f77d6e725.tar.gz
meson-d5ae94f571af17ec969a4320b54e322f77d6e725.tar.bz2
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
Diffstat (limited to 'mesonbuild')
-rw-r--r--mesonbuild/dependencies/dub.py86
1 files changed, 58 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