Skip to content

Commit 80d14d9

Browse files
committed
cargo: pick exact dependency version from Cargo.lock
A dependency might specify a version that is compatible with the one in Cargo.lock, but not the exact same version. Whenever Cargo.lock contains the package, only use the pinned versions that can be used; update the version in the manifest so that the correct API level is used as well. Originally by Xavier Claessens <xclaessens@netflix.com>, but almost completely rewritten.
1 parent 3869e95 commit 80d14d9

File tree

2 files changed

+26
-2
lines changed

2 files changed

+26
-2
lines changed

mesonbuild/cargo/interpreter.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
from . import builder, version, cfg
2121
from .toml import load_toml
2222
from .manifest import Manifest, CargoLock, fixup_meson_varname
23-
from ..mesonlib import MesonException, MachineChoice
23+
from ..mesonlib import MesonException, MachineChoice, version_compare
2424
from .. import coredata, mlog
2525
from ..wrap.wrap import PackageDefinition
2626

@@ -165,6 +165,19 @@ def _dep_package(self, dep: Dependency) -> PackageState:
165165
_, _, directory = _parse_git_url(dep.git, dep.branch)
166166
dep_pkg, _ = self._fetch_package_from_subproject(dep.package, directory)
167167
else:
168+
# From all available versions from Cargo.lock, pick the most recent
169+
# satisfying the constraints
170+
if self.cargolock:
171+
cargo_lock_pkgs = self.cargolock.named(dep.package)
172+
else:
173+
cargo_lock_pkgs = []
174+
for cargo_pkg in cargo_lock_pkgs:
175+
if all(version_compare(cargo_pkg.version, v) for v in dep.meson_version):
176+
dep.update_version(f'={cargo_pkg.version}')
177+
break
178+
else:
179+
if not dep.meson_version:
180+
raise MesonException(f'Cannot determine version of cargo package {dep.package}')
168181
dep_pkg, _ = self._fetch_package(dep.package, dep.api)
169182
return dep_pkg
170183

mesonbuild/cargo/manifest.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ def api(self) -> str:
255255
elif v.startswith('='):
256256
api.add(version.api(v[1:].strip()))
257257
if not api:
258-
return '0'
258+
return ''
259259
elif len(api) == 1:
260260
return api.pop()
261261
else:
@@ -281,6 +281,17 @@ def from_raw(cls, name: str, raw_depv: T.Union[raw.FromWorkspace, raw.Dependency
281281
raw_dep = _depv_to_dep(raw_depv)
282282
return cls.from_raw_dict(name, raw_dep, member_path, raw_ws_dep)
283283

284+
def update_version(self, v: str) -> None:
285+
self.version = v
286+
try:
287+
delattr(self, 'api')
288+
except AttributeError:
289+
pass
290+
try:
291+
delattr(self, 'meson_version')
292+
except AttributeError:
293+
pass
294+
284295

285296
@dataclasses.dataclass
286297
class BuildTarget(T.Generic[_R]):

0 commit comments

Comments
 (0)