Skip to content

Commit

Permalink
rust: suggest correct dependency when found in Cargo.lock
Browse files Browse the repository at this point in the history
As we refer to crates using API version instead of plain version, it can
be confusing to user which is left with a simple "Dependency X not
found".

Thus, when we detect that a rust dependency is missing, and is not
available using a wrap file, if we find something compatible using
Cargo.lock import, we just list the correct dependencies names.
  • Loading branch information
pbo-linaro committed Jul 21, 2024
1 parent 2548f92 commit 38d4b72
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 0 deletions.
17 changes: 17 additions & 0 deletions mesonbuild/interpreter/dependencyfallbacks.py
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,23 @@ def lookup(self, kwargs: TYPE_nkwargs, force_fallback: bool = False) -> Dependen
self._subproject_impl(subp_name, varname)
break

# Check if we could have a matching Rust crate imported from
# Cargo.lock, with expected api version. We know there is no
# wrap-file defined to match this crate.
if name.endswith('-rs') and required:
s = name.split('-')
if len(s) < 3:
continue
s.pop() # -rs
s.pop() # version
crate = '-'.join(s)
cargo_wraps = self.wrap_resolver.get_cargo_wraps(crate)
if not cargo_wraps:
continue
imports = ', '.join([f'"{n}"' for n in cargo_wraps])
raise DependencyException(f'Rust dependency "{name}" not found, '
f'but following versions were found using Cargo.lock import: {imports}')

candidates = self._get_candidates()

# writing just "dependency('')" is an error, because it can only fail
Expand Down
18 changes: 18 additions & 0 deletions mesonbuild/wrap/wrap.py
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,24 @@ def find_program_provider(self, names: T.List[str]) -> T.Optional[str]:
return wrap_name
return None

def get_cargo_wraps(self, cratename: str) -> T.List[str]:
found = []
for wrap in self.wraps.values():
if wrap.get('method') != 'cargo':
continue
if not wrap.name.endswith('-rs'):
continue
s = wrap.name.split('-')
if len(s) < 3:
continue
s.pop() # -rs
s.pop() # version
wrap_cratename = '-'.join(s)

if wrap_cratename == cratename:
found.append(wrap.name)
return found

def resolve(self, packagename: str, force_method: T.Optional[Method] = None) -> T.Tuple[str, Method]:
wrap = self.wraps.get(packagename)
if wrap is None:
Expand Down
25 changes: 25 additions & 0 deletions test cases/rust/26 cargo lock suggest dependency/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions test cases/rust/26 cargo lock suggest dependency/meson.build
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
project('cargo lock')

dependency('bar-1.0-rs')
7 changes: 7 additions & 0 deletions test cases/rust/26 cargo lock suggest dependency/test.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"stdout": [
{
"line": "test cases/rust/26 cargo lock suggest dependency/meson.build:3:0: ERROR: Rust dependency \"bar-1.0-rs\" not found, but following versions were found using Cargo.lock import: \"bar-1-rs\", \"bar-2-rs\", \"bar-0-rs\", \"bar-0.8-rs\""
}
]
}

0 comments on commit 38d4b72

Please sign in to comment.