summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mesonbuild/cargo/interpreter.py4
-rw-r--r--mesonbuild/cargo/manifest.py46
-rw-r--r--mesonbuild/cargo/version.py2
-rw-r--r--unittests/cargotests.py25
4 files changed, 44 insertions, 33 deletions
diff --git a/mesonbuild/cargo/interpreter.py b/mesonbuild/cargo/interpreter.py
index 1ef06aeb9..a0d4371be 100644
--- a/mesonbuild/cargo/interpreter.py
+++ b/mesonbuild/cargo/interpreter.py
@@ -263,7 +263,7 @@ class Interpreter:
def _create_system_dependency(self, name: str, dep: SystemDependency, build: builder.Builder) -> T.List[mparser.BaseNode]:
# TODO: handle feature_overrides
kw = {
- 'version': build.array([build.string(s) for s in dep.version]),
+ 'version': build.array([build.string(s) for s in dep.meson_version]),
'required': build.bool(not dep.optional),
}
varname = f'{fixup_meson_varname(name)}_system_dep'
@@ -290,7 +290,7 @@ class Interpreter:
def _create_dependency(self, dep: Dependency, build: builder.Builder) -> T.List[mparser.BaseNode]:
pkg = self._dep_package(dep)
kw = {
- 'version': build.array([build.string(s) for s in dep.version]),
+ 'version': build.array([build.string(s) for s in dep.meson_version]),
}
# Lookup for this dependency with the features we want in default_options kwarg.
#
diff --git a/mesonbuild/cargo/manifest.py b/mesonbuild/cargo/manifest.py
index 9f5b44d39..048a9e6f8 100644
--- a/mesonbuild/cargo/manifest.py
+++ b/mesonbuild/cargo/manifest.py
@@ -10,8 +10,8 @@ import os
import typing as T
from . import version
+from ..mesonlib import MesonException, lazy_property
from .. import mlog
-from ..mesonlib import MesonException
if T.TYPE_CHECKING:
from typing_extensions import Protocol, Self
@@ -65,7 +65,6 @@ def _raw_to_dataclass(raw: T.Mapping[str, object], cls: T.Type[_DI],
:param data: The raw data to look at
:param cls: The Dataclass derived type that will be created
:param msg: the header for the error message. Usually something like "In N structure".
- :param convert_version: whether to convert the version field to a Meson compatible one.
:return: The original data structure, but with all unknown keys removed.
"""
new_dict = {}
@@ -120,10 +119,9 @@ class Package:
autotests: bool = True
autobenches: bool = True
- api: str = dataclasses.field(init=False)
-
- def __post_init__(self) -> None:
- self.api = version.api(self.version)
+ @lazy_property
+ def api(self) -> str:
+ return version.api(self.version)
@classmethod
def from_raw(cls, raw_pkg: raw.Package) -> Self:
@@ -137,7 +135,7 @@ class SystemDependency:
"""
name: str
- version: T.List[str]
+ version: str = ''
optional: bool = False
feature: T.Optional[str] = None
# TODO: convert values to dataclass
@@ -146,18 +144,18 @@ class SystemDependency:
@classmethod
def from_raw(cls, name: str, raw: T.Union[T.Dict[str, T.Any], str]) -> SystemDependency:
if isinstance(raw, str):
- return cls(name, SystemDependency.convert_version(raw))
+ raw = {'version': raw}
name = raw.get('name', name)
- version = SystemDependency.convert_version(raw.get('version', ''))
+ version = raw.get('version', '')
optional = raw.get('optional', False)
feature = raw.get('feature')
# Everything else are overrides when certain features are enabled.
feature_overrides = {k: v for k, v in raw.items() if k not in {'name', 'version', 'optional', 'feature'}}
return cls(name, version, optional, feature, feature_overrides)
- @staticmethod
- def convert_version(version: T.Optional[str]) -> T.List[str]:
- vers = version.split(',') if version else []
+ @lazy_property
+ def meson_version(self) -> T.List[str]:
+ vers = self.version.split(',') if self.version else []
result: T.List[str] = []
for v in vers:
v = v.strip()
@@ -175,7 +173,7 @@ class Dependency:
"""Representation of a Cargo Dependency Entry."""
package: str
- version: T.List[str]
+ version: str = ''
registry: T.Optional[str] = None
git: T.Optional[str] = None
branch: T.Optional[str] = None
@@ -185,28 +183,30 @@ class Dependency:
default_features: bool = True
features: T.List[str] = dataclasses.field(default_factory=list)
- api: str = dataclasses.field(init=False)
+ @lazy_property
+ def meson_version(self) -> T.List[str]:
+ return version.convert(self.version)
- def __post_init__(self) -> None:
+ @lazy_property
+ def api(self) -> str:
# Extract wanted API version from version constraints.
api = set()
- for v in self.version:
+ for v in self.meson_version:
if v.startswith(('>=', '==')):
api.add(version.api(v[2:].strip()))
elif v.startswith('='):
api.add(version.api(v[1:].strip()))
if not api:
- self.api = '0'
+ return '0'
elif len(api) == 1:
- self.api = api.pop()
+ return api.pop()
else:
raise MesonException(f'Cannot determine minimum API version from {self.version}.')
@classmethod
def from_raw_dict(cls, name: str, raw_dep: raw.Dependency) -> Dependency:
raw_dep.setdefault('package', name)
- return _raw_to_dataclass(raw_dep, cls, f'Dependency entry {name}',
- version=version.convert)
+ return _raw_to_dataclass(raw_dep, cls, f'Dependency entry {name}')
@classmethod
def from_raw(cls, name: str, raw_depv: raw.DependencyV) -> Dependency:
@@ -344,7 +344,6 @@ class Manifest:
dependencies: T.Dict[str, Dependency] = dataclasses.field(default_factory=dict)
dev_dependencies: T.Dict[str, Dependency] = dataclasses.field(default_factory=dict)
build_dependencies: T.Dict[str, Dependency] = dataclasses.field(default_factory=dict)
- system_dependencies: T.Dict[str, SystemDependency] = dataclasses.field(init=False)
lib: T.Optional[Library] = None
bin: T.List[Binary] = dataclasses.field(default_factory=list)
test: T.List[Test] = dataclasses.field(default_factory=list)
@@ -357,7 +356,10 @@ class Manifest:
def __post_init__(self) -> None:
self.features.setdefault('default', [])
- self.system_dependencies = {k: SystemDependency.from_raw(k, v) for k, v in self.package.metadata.get('system-deps', {}).items()}
+
+ @lazy_property
+ def system_dependencies(self) -> T.Dict[str, SystemDependency]:
+ return {k: SystemDependency.from_raw(k, v) for k, v in self.package.metadata.get('system-deps', {}).items()}
@classmethod
def from_raw(cls, raw: raw.Manifest, path: str = '') -> Self:
diff --git a/mesonbuild/cargo/version.py b/mesonbuild/cargo/version.py
index 51ce79b04..ce5894528 100644
--- a/mesonbuild/cargo/version.py
+++ b/mesonbuild/cargo/version.py
@@ -27,6 +27,8 @@ def convert(cargo_ver: str) -> T.List[str]:
"""
# Cleanup, just for safety
cargo_ver = cargo_ver.strip()
+ if not cargo_ver:
+ return []
cargo_vers = [c.strip() for c in cargo_ver.split(',')]
out: T.List[str] = []
diff --git a/unittests/cargotests.py b/unittests/cargotests.py
index bb0a32ed2..68b15f8cf 100644
--- a/unittests/cargotests.py
+++ b/unittests/cargotests.py
@@ -299,28 +299,34 @@ class CargoTomlTest(unittest.TestCase):
self.assertEqual(len(manifest.dependencies), 6)
self.assertEqual(manifest.dependencies['gtk'].package, 'gtk4')
- self.assertEqual(manifest.dependencies['gtk'].version, ['>= 0.9', '< 0.10'])
+ self.assertEqual(manifest.dependencies['gtk'].version, '0.9')
+ self.assertEqual(manifest.dependencies['gtk'].meson_version, ['>= 0.9', '< 0.10'])
self.assertEqual(manifest.dependencies['gtk'].api, '0.9')
self.assertEqual(manifest.dependencies['num-complex'].package, 'num-complex')
- self.assertEqual(manifest.dependencies['num-complex'].version, ['>= 0.4', '< 0.5'])
- self.assertEqual(manifest.dependencies['num-complex'].api, '0.4')
+ self.assertEqual(manifest.dependencies['num-complex'].version, '0.4')
+ self.assertEqual(manifest.dependencies['num-complex'].meson_version, ['>= 0.4', '< 0.5'])
self.assertEqual(manifest.dependencies['rayon'].package, 'rayon')
- self.assertEqual(manifest.dependencies['rayon'].version, ['>= 1.0', '< 2'])
+ self.assertEqual(manifest.dependencies['rayon'].version, '1.0')
+ self.assertEqual(manifest.dependencies['rayon'].meson_version, ['>= 1.0', '< 2'])
self.assertEqual(manifest.dependencies['rayon'].api, '1')
self.assertEqual(manifest.dependencies['once_cell'].package, 'once_cell')
- self.assertEqual(manifest.dependencies['once_cell'].version, ['>= 1', '< 2'])
+ self.assertEqual(manifest.dependencies['once_cell'].version, '1')
+ self.assertEqual(manifest.dependencies['once_cell'].meson_version, ['>= 1', '< 2'])
self.assertEqual(manifest.dependencies['once_cell'].api, '1')
self.assertEqual(manifest.dependencies['async-channel'].package, 'async-channel')
- self.assertEqual(manifest.dependencies['async-channel'].version, ['>= 2.0', '< 3'])
+ self.assertEqual(manifest.dependencies['async-channel'].version, '2.0')
+ self.assertEqual(manifest.dependencies['async-channel'].meson_version, ['>= 2.0', '< 3'])
self.assertEqual(manifest.dependencies['async-channel'].api, '2')
self.assertEqual(manifest.dependencies['zerocopy'].package, 'zerocopy')
- self.assertEqual(manifest.dependencies['zerocopy'].version, ['>= 0.7', '< 0.8'])
+ self.assertEqual(manifest.dependencies['zerocopy'].version, '0.7')
+ self.assertEqual(manifest.dependencies['zerocopy'].meson_version, ['>= 0.7', '< 0.8'])
self.assertEqual(manifest.dependencies['zerocopy'].features, ['derive'])
self.assertEqual(manifest.dependencies['zerocopy'].api, '0.7')
self.assertEqual(len(manifest.dev_dependencies), 1)
self.assertEqual(manifest.dev_dependencies['gir-format-check'].package, 'gir-format-check')
- self.assertEqual(manifest.dev_dependencies['gir-format-check'].version, ['>= 0.1', '< 0.2'])
+ self.assertEqual(manifest.dev_dependencies['gir-format-check'].version, '^0.1')
+ self.assertEqual(manifest.dev_dependencies['gir-format-check'].meson_version, ['>= 0.1', '< 0.2'])
self.assertEqual(manifest.dev_dependencies['gir-format-check'].api, '0.1')
def test_cargo_toml_targets(self) -> None:
@@ -371,7 +377,8 @@ class CargoTomlTest(unittest.TestCase):
self.assertEqual(len(manifest.system_dependencies), 1)
self.assertEqual(manifest.system_dependencies['pango'].name, 'pango')
- self.assertEqual(manifest.system_dependencies['pango'].version, ['>=1.40'])
+ self.assertEqual(manifest.system_dependencies['pango'].version, '1.40')
+ self.assertEqual(manifest.system_dependencies['pango'].meson_version, ['>=1.40'])
self.assertEqual(manifest.system_dependencies['pango'].optional, False)
self.assertEqual(manifest.system_dependencies['pango'].feature, None)