Skip to content

Commit 3869e95

Browse files
committed
cargo: improve error message for dependency version conflicts
While developing I often got a confusing 'Neither a subproject directory nor a None.wrap file was found'. Replace it with a clear message that explains: 1. Which dependency couldn't be found 2. What versions are available in the root Cargo.lock 3. That this is likely a version conflict 4. How to fix it (update dependencies to match root Cargo.lock) Example: ERROR: Dependency 'socket2-0.4-rs' not found. Root Cargo.lock provides: socket2-0.5-rs, socket2-0.6-rs. This could be a Meson bug, please report it. I am actually not sure if this is really always a Meson bug. But to be safe, suggest reporting it until more experience is gained. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
1 parent b570aaf commit 3869e95

File tree

2 files changed

+33
-1
lines changed

2 files changed

+33
-1
lines changed

mesonbuild/cargo/interpreter.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,17 @@ def _fetch_package(self, package_name: str, api: str) -> T.Tuple[PackageState, b
124124

125125
def _fetch_package_from_subproject(self, package_name: str, meson_depname: str) -> T.Tuple[PackageState, bool]:
126126
subp_name, _ = self.environment.wrap_resolver.find_dep_provider(meson_depname)
127+
if subp_name is None:
128+
# If Cargo.lock has a different version, this could be a resolution
129+
# bug, but maybe also a version mismatch? I am not sure yet...
130+
similar_deps = [pkg.subproject
131+
for pkg in self.cargolock.named(package_name)]
132+
if similar_deps:
133+
similar_msg = f'Cargo.lock provides: {", ".join(similar_deps)}.'
134+
else:
135+
similar_msg = 'Cargo.lock does not contain this crate name.'
136+
raise MesonException(f'Dependency {meson_depname!r} not found in any wrap files or Cargo.lock; {similar_msg} This could be a Meson bug, please report it.')
137+
127138
subdir, _ = self.environment.wrap_resolver.resolve(subp_name)
128139
subprojects_dir = os.path.join(subdir, 'subprojects')
129140
self.environment.wrap_resolver.load_and_merge(subprojects_dir, T.cast('SubProject', meson_depname))

mesonbuild/cargo/manifest.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,13 @@
55

66
from __future__ import annotations
77

8+
import collections
89
import dataclasses
910
import os
1011
import typing as T
1112

1213
from . import version
13-
from ..mesonlib import MesonException, lazy_property
14+
from ..mesonlib import MesonException, lazy_property, Version
1415
from .. import mlog
1516

1617
if T.TYPE_CHECKING:
@@ -489,6 +490,14 @@ class CargoLockPackage:
489490
checksum: T.Optional[str] = None
490491
dependencies: T.List[str] = dataclasses.field(default_factory=list)
491492

493+
@lazy_property
494+
def api(self) -> str:
495+
return version.api(self.version)
496+
497+
@lazy_property
498+
def subproject(self) -> str:
499+
return f'{self.name}-{self.api}-rs'
500+
492501
@classmethod
493502
def from_raw(cls, raw: raw.CargoLockPackage) -> CargoLockPackage:
494503
return _raw_to_dataclass(raw, cls, 'Cargo.lock package')
@@ -508,3 +517,15 @@ class CargoLock:
508517
def from_raw(cls, raw: raw.CargoLock) -> CargoLock:
509518
return _raw_to_dataclass(raw, cls, 'Cargo.lock',
510519
package=lambda x: [CargoLockPackage.from_raw(p) for p in x])
520+
521+
def named(self, name: str) -> T.Sequence[CargoLockPackage]:
522+
return self._versions[name]
523+
524+
@lazy_property
525+
def _versions(self) -> T.Dict[str, T.List[CargoLockPackage]]:
526+
versions = collections.defaultdict(list)
527+
for pkg in self.package:
528+
versions[pkg.name].append(pkg)
529+
for pkg_versions in versions.values():
530+
pkg_versions.sort(reverse=True, key=lambda pkg: Version(pkg.version))
531+
return versions

0 commit comments

Comments
 (0)