diff options
| -rw-r--r-- | mesonbuild/cargo/interpreter.py | 4 | ||||
| -rw-r--r-- | mesonbuild/cargo/manifest.py | 46 | ||||
| -rw-r--r-- | mesonbuild/cargo/version.py | 2 | ||||
| -rw-r--r-- | unittests/cargotests.py | 25 |
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) |
