mirror of
https://github.com/mesonbuild/meson.git
synced 2026-11-06 05:16:42 +00:00
cargo: flatten [target] into the unconditional tables
This simplifies the parsing and makes it possible to handle correctly dependency-named features, which apply equally to all dependencies, even those that are disabled. In other words, even if a "win" dependency is only declared under [target.'cfg(windows)'.dependencies], "cargo build --features win" succeeds on non-Windows platforms as well. Due to the new representation, move the merged table into PackageConfiguration. This is cleaner, because it doesn't modify the manifest, and it makes it possible to fully separate dependencies for the host and build machines. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
1 parent
5f6eb8a7c8
commit
4b3ceff48c
4 files changed
+125
-99
No files matched your search
@@ -64,6 +64,9 @@ def _extra_deps_varname() -> str:
|
||||
class PackageConfiguration:
|
||||
"""Configuration for a package during dependency resolution."""
|
||||
for_machine: MachineChoice
|
||||
# Dependency table of the package, with the [target.*] sections that apply
|
||||
# to this machine merged in.
|
||||
dependencies: T.Dict[str, Dependency] = dataclasses.field(default_factory=dict)
|
||||
features: T.Set[str] = dataclasses.field(default_factory=set)
|
||||
required_deps: T.Set[str] = dataclasses.field(default_factory=set)
|
||||
optional_deps_features: T.Dict[str, T.Set[str]] = dataclasses.field(default_factory=lambda: collections.defaultdict(set))
|
||||
@@ -77,11 +80,11 @@ class PackageConfiguration:
|
||||
args.extend(['--cfg', f'feature="{feature}"'])
|
||||
return args
|
||||
|
||||
def get_dependency_map(self, manifest: Manifest) -> T.Dict[str, str]:
|
||||
def get_dependency_map(self) -> T.Dict[str, str]:
|
||||
"""Get the rust dependency mapping for this package configuration."""
|
||||
dependency_map: T.Dict[str, str] = {}
|
||||
for name in sorted(self.required_deps):
|
||||
dep = manifest.dependencies[name]
|
||||
dep = self.dependencies[name]
|
||||
dep_key = PackageKey(dep.package, dep.api)
|
||||
dep_pkg = self.dep_packages[dep_key]
|
||||
dep_lib_name = dep_pkg.library_name(self.for_machine)
|
||||
@@ -458,7 +461,7 @@ class Interpreter:
|
||||
if not cfg:
|
||||
continue
|
||||
for depname in cfg.required_deps:
|
||||
dep = pkg.manifest.dependencies[depname]
|
||||
dep = cfg.dependencies[depname]
|
||||
if dep.path:
|
||||
dep_member = as_posix(pkg.ws_member, dep.path)
|
||||
if not ws.workspace.is_excluded(dep_member):
|
||||
@@ -652,30 +655,38 @@ class Interpreter:
|
||||
if pkg.cfg[machine] is not None:
|
||||
return # Already prepared for this machine
|
||||
|
||||
pkg.cfg[machine] = PackageConfiguration(for_machine=machine)
|
||||
cfg = PackageConfiguration(for_machine=machine)
|
||||
pkg.cfg[machine] = cfg
|
||||
|
||||
# Merge target-specific dependencies that are enabled for this machine
|
||||
# Keep the dependencies whose [target.*] condition holds for this machine.
|
||||
# A later entry wins, so an unconditional declaration is the fallback for
|
||||
# the name and a matching [target.*] one overrides it.
|
||||
rustc = T.cast('RustCompiler', self.environment.coredata.compilers[machine]['rust'])
|
||||
target_cfgs = self._get_cfgs(machine, pkg.get_subproject_name())
|
||||
for condition, dependencies in pkg.manifest.target.items():
|
||||
if condition == rustc.get_target_triple() or eval_cfg(condition, target_cfgs):
|
||||
pkg.manifest.dependencies.update(dependencies)
|
||||
|
||||
def enabled(dep: Dependency) -> bool:
|
||||
return dep.target is None or dep.target == rustc.get_target_triple() or \
|
||||
eval_cfg(dep.target, target_cfgs)
|
||||
|
||||
cfg.dependencies = {name: dep
|
||||
for name, deps in pkg.manifest.dependencies.items()
|
||||
for dep in deps if enabled(dep)}
|
||||
|
||||
# If you specify the optional dependency with the dep: prefix anywhere in the [features]
|
||||
# table, that disables the implicit feature.
|
||||
deps = set(feature[4:]
|
||||
for feature in itertools.chain.from_iterable(pkg.manifest.features.values())
|
||||
if feature.startswith('dep:'))
|
||||
for name, dep in itertools.chain(pkg.manifest.dependencies.items(),
|
||||
pkg.manifest.dev_dependencies.items(),
|
||||
pkg.manifest.build_dependencies.items()):
|
||||
if dep.optional and name not in deps:
|
||||
pkg.manifest.features.setdefault(name, [])
|
||||
pkg.manifest.features[name].append(f'dep:{name}')
|
||||
deps.add(name)
|
||||
explicit = set(feature[4:]
|
||||
for feature in itertools.chain.from_iterable(pkg.manifest.features.values())
|
||||
if feature.startswith('dep:'))
|
||||
# Cargo forbids [dev-dependencies] to be optional, so skip them
|
||||
for table in (pkg.manifest.dependencies, pkg.manifest.build_dependencies):
|
||||
for name, deps in table.items():
|
||||
if any(dep.optional for dep in deps) and name not in explicit:
|
||||
pkg.manifest.features.setdefault(name, [])
|
||||
pkg.manifest.features[name].append(f'dep:{name}')
|
||||
explicit.add(name)
|
||||
|
||||
# Fetch required dependencies recursively for this machine
|
||||
for depname, dep in pkg.manifest.dependencies.items():
|
||||
for depname, dep in cfg.dependencies.items():
|
||||
if not dep.optional:
|
||||
self._add_dependency(pkg, depname, machine)
|
||||
|
||||
@@ -741,7 +752,7 @@ class Interpreter:
|
||||
cfg = pkg.cfg[machine]
|
||||
if depname in cfg.required_deps:
|
||||
return
|
||||
dep = pkg.manifest.dependencies.get(depname)
|
||||
dep = cfg.dependencies.get(depname)
|
||||
if not dep:
|
||||
# It could be build/dev/target dependency. Just ignore it.
|
||||
return
|
||||
@@ -772,7 +783,7 @@ class Interpreter:
|
||||
else:
|
||||
self._add_dependency(pkg, depname, machine)
|
||||
if depname in cfg.required_deps:
|
||||
dep = pkg.manifest.dependencies[depname]
|
||||
dep = cfg.dependencies[depname]
|
||||
dep_pkg = self._dep_package(pkg, dep, cfg)
|
||||
# Use machines_from() to determine which machines the dependency needs
|
||||
for dep_machine in dep_pkg.manifest.machines_from(machine, self.is_cross):
|
||||
|
||||
@@ -25,6 +25,8 @@ if T.TYPE_CHECKING:
|
||||
from ..options import ElementaryOptionValues
|
||||
from ..wrap.wrap import PackageDefinition
|
||||
|
||||
RawTargetTables = T.Mapping[str, T.Mapping[str, T.Mapping[str, raw.FromWorkspace | raw.DependencyV | str]]]
|
||||
|
||||
# Copied from typeshed. Blarg that they don't expose this
|
||||
class DataclassInstance(Protocol):
|
||||
__dataclass_fields__: T.ClassVar[dict[str, dataclasses.Field[T.Any]]]
|
||||
@@ -305,6 +307,8 @@ class Dependency:
|
||||
optional: bool = False
|
||||
default_features: bool = True
|
||||
features: T.List[str] = dataclasses.field(default_factory=list)
|
||||
# The [target.<cfg>] condition this entry was declared under, if any.
|
||||
target: T.Optional[str] = None
|
||||
|
||||
@lazy_property
|
||||
def accepts_version(self) -> T.Callable[[str], bool]:
|
||||
@@ -340,7 +344,7 @@ class Dependency:
|
||||
return {'version': depv} if isinstance(depv, str) else depv
|
||||
|
||||
@classmethod
|
||||
def from_raw(cls, name: str, raw_depv: T.Union[raw.FromWorkspace, raw.DependencyV], member_path: str = '', workspace: T.Optional[Workspace] = None) -> Self:
|
||||
def from_raw(cls, name: str, raw_depv: T.Union[raw.FromWorkspace, raw.DependencyV], member_path: str = '', workspace: T.Optional[Workspace] = None, target: T.Optional[str] = None) -> Self:
|
||||
"""Create a dependency from a raw cargo dictionary or string"""
|
||||
raw_ws_dep = workspace.dependencies.get(name) if workspace else None
|
||||
raw_ws_dep = cls._depv_to_dep(raw_ws_dep or {})
|
||||
@@ -353,10 +357,12 @@ class Dependency:
|
||||
return as_posix(ws_path, relative_to=member_path)
|
||||
return None
|
||||
|
||||
return _raw_to_dataclass(raw_dep, cls, f'Dependency entry {name}', raw_ws_dep,
|
||||
package=DefaultValue(name),
|
||||
path=MergeValue(path_convertor),
|
||||
features=MergeValue(lambda features, ws_features: (features or []) + (ws_features or [])))
|
||||
dep = _raw_to_dataclass(raw_dep, cls, f'Dependency entry {name}', raw_ws_dep,
|
||||
package=DefaultValue(name),
|
||||
path=MergeValue(path_convertor),
|
||||
features=MergeValue(lambda features, ws_features: (features or []) + (ws_features or [])))
|
||||
dep.target = target
|
||||
return dep
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
@@ -596,16 +602,16 @@ class Manifest:
|
||||
"""
|
||||
|
||||
package: Package
|
||||
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)
|
||||
# Note that these three fields also include the [target] sections.
|
||||
dependencies: T.Dict[str, T.List[Dependency]] = dataclasses.field(default_factory=dict)
|
||||
dev_dependencies: T.Dict[str, T.List[Dependency]] = dataclasses.field(default_factory=dict)
|
||||
build_dependencies: T.Dict[str, T.List[Dependency]] = dataclasses.field(default_factory=dict)
|
||||
lib: T.Optional[Library] = None
|
||||
bin: T.Dict[str, Binary] = dataclasses.field(default_factory=dict)
|
||||
test: T.List[Test] = dataclasses.field(default_factory=list)
|
||||
bench: T.List[Benchmark] = dataclasses.field(default_factory=list)
|
||||
example: T.List[Example] = dataclasses.field(default_factory=list)
|
||||
features: T.Dict[str, T.List[str]] = dataclasses.field(default_factory=dict)
|
||||
target: T.Dict[str, T.Dict[str, Dependency]] = dataclasses.field(default_factory=dict)
|
||||
lints: T.List[Lint] = dataclasses.field(default_factory=list)
|
||||
profile: T.Dict[str, Profile] = dataclasses.field(default_factory=dict)
|
||||
|
||||
@@ -620,11 +626,8 @@ class Manifest:
|
||||
"""Every path dependency of the package, including the ones that a
|
||||
[target] condition or an unused optional keeps out of the resolved
|
||||
dependency graph."""
|
||||
for dep in self.dependencies.values():
|
||||
if dep.path:
|
||||
yield dep
|
||||
for deps in self.target.values():
|
||||
for dep in deps.values():
|
||||
for deps in self.dependencies.values():
|
||||
for dep in deps:
|
||||
if dep.path:
|
||||
yield dep
|
||||
|
||||
@@ -688,27 +691,39 @@ class Manifest:
|
||||
f'({autobins[bin_name].path} and {bin_path})')
|
||||
autobins[bin_name] = Binary.from_raw({'name': bin_name, 'path': bin_path}, pkg)
|
||||
|
||||
def dependencies_from_raw(x: T.Dict[str, T.Any]) -> T.Dict[str, Dependency]:
|
||||
return {k: Dependency.from_raw(k, v, member_path, workspace) for k, v in x.items()}
|
||||
def dependencies_from_raw(x: T.Dict[str, T.Any]) -> T.Dict[str, T.List[Dependency]]:
|
||||
return {k: [Dependency.from_raw(k, v, member_path, workspace)] for k, v in x.items()}
|
||||
|
||||
return _raw_to_dataclass(raw, cls, f'Cargo.toml package {pkg.name}',
|
||||
raw_from_workspace=workspace.inheritable if workspace else None,
|
||||
ignored_fields=['badges', 'workspace'],
|
||||
package=ConvertValue(lambda _: pkg),
|
||||
dependencies=ConvertValue(dependencies_from_raw),
|
||||
dev_dependencies=ConvertValue(dependencies_from_raw),
|
||||
build_dependencies=ConvertValue(dependencies_from_raw),
|
||||
lints=ConvertValue(Lint.from_raw),
|
||||
lib=ConvertValue(lambda x: Library.from_raw(x, pkg), default=autolib),
|
||||
bin=DictMergeValue(lambda x: [Binary.from_raw(b, pkg) for b in x],
|
||||
merge_key=lambda x: x.path,
|
||||
out_key=lambda x: x.name,
|
||||
base=autobins),
|
||||
test=ConvertValue(lambda x: [Test.from_raw(b, pkg) for b in x]),
|
||||
bench=ConvertValue(lambda x: [Benchmark.from_raw(b, pkg) for b in x]),
|
||||
example=ConvertValue(lambda x: [Example.from_raw(b, pkg) for b in x]),
|
||||
target=ConvertValue(lambda x: {k: dependencies_from_raw(v.get('dependencies', {})) for k, v in x.items()}),
|
||||
profile=ConvertValue(lambda x: {k: Profile.from_raw(v) for k, v in x.items()}))
|
||||
manifest = _raw_to_dataclass(raw, cls, f'Cargo.toml package {pkg.name}',
|
||||
raw_from_workspace=workspace.inheritable if workspace else None,
|
||||
ignored_fields=['badges', 'workspace', 'target'],
|
||||
package=ConvertValue(lambda _: pkg),
|
||||
dependencies=ConvertValue(dependencies_from_raw),
|
||||
dev_dependencies=ConvertValue(dependencies_from_raw),
|
||||
build_dependencies=ConvertValue(dependencies_from_raw),
|
||||
lints=ConvertValue(Lint.from_raw),
|
||||
lib=ConvertValue(lambda x: Library.from_raw(x, pkg), default=autolib),
|
||||
bin=DictMergeValue(lambda x: [Binary.from_raw(b, pkg) for b in x],
|
||||
merge_key=lambda x: x.path,
|
||||
out_key=lambda x: x.name,
|
||||
base=autobins),
|
||||
test=ConvertValue(lambda x: [Test.from_raw(b, pkg) for b in x]),
|
||||
bench=ConvertValue(lambda x: [Benchmark.from_raw(b, pkg) for b in x]),
|
||||
example=ConvertValue(lambda x: [Example.from_raw(b, pkg) for b in x]),
|
||||
profile=ConvertValue(lambda x: {k: Profile.from_raw(v) for k, v in x.items()}))
|
||||
|
||||
# Merge [target.<cfg>] into the three tables for unconditional dependencies.
|
||||
# They go in after the unconditional entries, so that a matching condition
|
||||
# overrides the plain declaration of the same name.
|
||||
target_tables = T.cast('RawTargetTables', raw.get('target', {}))
|
||||
for condition, tables in target_tables.items():
|
||||
for table_name in ('dependencies', 'dev-dependencies', 'build-dependencies'):
|
||||
deps = getattr(manifest, fixup_meson_varname(table_name))
|
||||
for name, v in tables.get(table_name, {}).items():
|
||||
dep = Dependency.from_raw(name, v, member_path, workspace, target=condition)
|
||||
deps.setdefault(name, []).append(dep)
|
||||
|
||||
return manifest
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
|
||||
@@ -301,7 +301,7 @@ class RustCrate(ModuleObject):
|
||||
@TypedArgs('rust_crate.rust_dependency_map')
|
||||
def rust_dependency_map_method(self, state: ModuleState, args: T.List, kwargs: TYPE_kwargs) -> T.Dict[str, str]:
|
||||
"""Returns rust dependency mapping for this package."""
|
||||
return self.cfg.get_dependency_map(self.package.manifest)
|
||||
return self.cfg.get_dependency_map()
|
||||
|
||||
|
||||
class RustPackage(RustCrate):
|
||||
@@ -394,7 +394,7 @@ class RustPackage(RustCrate):
|
||||
kwargs['dependencies'].extend(deps)
|
||||
|
||||
depmap = kwargs['rust_dependency_map']
|
||||
kwargs['rust_dependency_map'] = cfg.get_dependency_map(self.package.manifest)
|
||||
kwargs['rust_dependency_map'] = cfg.get_dependency_map()
|
||||
kwargs['rust_dependency_map'].update(depmap)
|
||||
|
||||
rust_args = kwargs['rust_args']
|
||||
|
||||
+42
-42
@@ -633,50 +633,50 @@ class CargoTomlTest(unittest.TestCase):
|
||||
manifest = Manifest.from_raw(manifest_toml, 'Cargo.toml')
|
||||
|
||||
self.assertEqual(len(manifest.dependencies), 6)
|
||||
self.assertEqual(manifest.dependencies['gtk'].package, 'gtk4')
|
||||
self.assertEqual(manifest.dependencies['gtk'].version, '0.9')
|
||||
self.assertTrue(manifest.dependencies['gtk'].accepts_version('0.9'))
|
||||
self.assertFalse(manifest.dependencies['gtk'].accepts_version('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')
|
||||
self.assertTrue(manifest.dependencies['num-complex'].accepts_version('0.4'))
|
||||
self.assertFalse(manifest.dependencies['num-complex'].accepts_version('0.5'))
|
||||
self.assertEqual(manifest.dependencies['rayon'].package, 'rayon')
|
||||
self.assertEqual(manifest.dependencies['rayon'].version, '1.0')
|
||||
self.assertTrue(manifest.dependencies['rayon'].accepts_version('1.0'))
|
||||
self.assertTrue(manifest.dependencies['rayon'].accepts_version('1.23'))
|
||||
self.assertFalse(manifest.dependencies['rayon'].accepts_version('2.0'))
|
||||
self.assertFalse(manifest.dependencies['rayon'].accepts_version('2.0-pre1'))
|
||||
self.assertEqual(manifest.dependencies['rayon'].api, '1')
|
||||
self.assertEqual(manifest.dependencies['once_cell'].package, 'once_cell')
|
||||
self.assertEqual(manifest.dependencies['once_cell'].version, '1')
|
||||
self.assertTrue(manifest.dependencies['once_cell'].accepts_version('1.0'))
|
||||
self.assertTrue(manifest.dependencies['once_cell'].accepts_version('1.23'))
|
||||
self.assertFalse(manifest.dependencies['once_cell'].accepts_version('2.0'))
|
||||
self.assertFalse(manifest.dependencies['once_cell'].accepts_version('2.0-pre1'))
|
||||
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.1')
|
||||
self.assertFalse(manifest.dependencies['async-channel'].accepts_version('2.0'))
|
||||
self.assertTrue(manifest.dependencies['async-channel'].accepts_version('2.1'))
|
||||
self.assertTrue(manifest.dependencies['async-channel'].accepts_version('2.23'))
|
||||
self.assertFalse(manifest.dependencies['async-channel'].accepts_version('2.0'))
|
||||
self.assertFalse(manifest.dependencies['async-channel'].accepts_version('2.0-pre1'))
|
||||
self.assertEqual(manifest.dependencies['async-channel'].api, '2')
|
||||
self.assertEqual(manifest.dependencies['zerocopy'].package, 'zerocopy')
|
||||
self.assertEqual(manifest.dependencies['zerocopy'].version, '0.7')
|
||||
self.assertTrue(manifest.dependencies['zerocopy'].accepts_version('0.7'))
|
||||
self.assertFalse(manifest.dependencies['zerocopy'].accepts_version('0.8'))
|
||||
self.assertEqual(manifest.dependencies['zerocopy'].features, ['derive'])
|
||||
self.assertEqual(manifest.dependencies['zerocopy'].api, '0.7')
|
||||
self.assertEqual(manifest.dependencies['gtk'][0].package, 'gtk4')
|
||||
self.assertEqual(manifest.dependencies['gtk'][0].version, '0.9')
|
||||
self.assertTrue(manifest.dependencies['gtk'][0].accepts_version('0.9'))
|
||||
self.assertFalse(manifest.dependencies['gtk'][0].accepts_version('0.10'))
|
||||
self.assertEqual(manifest.dependencies['gtk'][0].api, '0.9')
|
||||
self.assertEqual(manifest.dependencies['num-complex'][0].package, 'num-complex')
|
||||
self.assertEqual(manifest.dependencies['num-complex'][0].version, '0.4')
|
||||
self.assertTrue(manifest.dependencies['num-complex'][0].accepts_version('0.4'))
|
||||
self.assertFalse(manifest.dependencies['num-complex'][0].accepts_version('0.5'))
|
||||
self.assertEqual(manifest.dependencies['rayon'][0].package, 'rayon')
|
||||
self.assertEqual(manifest.dependencies['rayon'][0].version, '1.0')
|
||||
self.assertTrue(manifest.dependencies['rayon'][0].accepts_version('1.0'))
|
||||
self.assertTrue(manifest.dependencies['rayon'][0].accepts_version('1.23'))
|
||||
self.assertFalse(manifest.dependencies['rayon'][0].accepts_version('2.0'))
|
||||
self.assertFalse(manifest.dependencies['rayon'][0].accepts_version('2.0-pre1'))
|
||||
self.assertEqual(manifest.dependencies['rayon'][0].api, '1')
|
||||
self.assertEqual(manifest.dependencies['once_cell'][0].package, 'once_cell')
|
||||
self.assertEqual(manifest.dependencies['once_cell'][0].version, '1')
|
||||
self.assertTrue(manifest.dependencies['once_cell'][0].accepts_version('1.0'))
|
||||
self.assertTrue(manifest.dependencies['once_cell'][0].accepts_version('1.23'))
|
||||
self.assertFalse(manifest.dependencies['once_cell'][0].accepts_version('2.0'))
|
||||
self.assertFalse(manifest.dependencies['once_cell'][0].accepts_version('2.0-pre1'))
|
||||
self.assertEqual(manifest.dependencies['once_cell'][0].api, '1')
|
||||
self.assertEqual(manifest.dependencies['async-channel'][0].package, 'async-channel')
|
||||
self.assertEqual(manifest.dependencies['async-channel'][0].version, '2.1')
|
||||
self.assertFalse(manifest.dependencies['async-channel'][0].accepts_version('2.0'))
|
||||
self.assertTrue(manifest.dependencies['async-channel'][0].accepts_version('2.1'))
|
||||
self.assertTrue(manifest.dependencies['async-channel'][0].accepts_version('2.23'))
|
||||
self.assertFalse(manifest.dependencies['async-channel'][0].accepts_version('2.0'))
|
||||
self.assertFalse(manifest.dependencies['async-channel'][0].accepts_version('2.0-pre1'))
|
||||
self.assertEqual(manifest.dependencies['async-channel'][0].api, '2')
|
||||
self.assertEqual(manifest.dependencies['zerocopy'][0].package, 'zerocopy')
|
||||
self.assertEqual(manifest.dependencies['zerocopy'][0].version, '0.7')
|
||||
self.assertTrue(manifest.dependencies['zerocopy'][0].accepts_version('0.7'))
|
||||
self.assertFalse(manifest.dependencies['zerocopy'][0].accepts_version('0.8'))
|
||||
self.assertEqual(manifest.dependencies['zerocopy'][0].features, ['derive'])
|
||||
self.assertEqual(manifest.dependencies['zerocopy'][0].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')
|
||||
self.assertTrue(manifest.dev_dependencies['gir-format-check'].accepts_version('0.1'))
|
||||
self.assertFalse(manifest.dev_dependencies['gir-format-check'].accepts_version('0.2'))
|
||||
self.assertEqual(manifest.dev_dependencies['gir-format-check'].api, '0.1')
|
||||
self.assertEqual(manifest.dev_dependencies['gir-format-check'][0].package, 'gir-format-check')
|
||||
self.assertEqual(manifest.dev_dependencies['gir-format-check'][0].version, '^0.1')
|
||||
self.assertTrue(manifest.dev_dependencies['gir-format-check'][0].accepts_version('0.1'))
|
||||
self.assertFalse(manifest.dev_dependencies['gir-format-check'][0].accepts_version('0.2'))
|
||||
self.assertEqual(manifest.dev_dependencies['gir-format-check'][0].api, '0.1')
|
||||
|
||||
def test_cargo_toml_proc_macro(self) -> None:
|
||||
with tempfile.TemporaryDirectory() as tmpdir:
|
||||
|
||||
Reference in new issue
Block a user