Repository: conan-io/conan
Pull request #16841 (2024-08-18 19:10:30)

lockfile error msg
Changelog: Fix: Improve error message when a lockfile fails to lock a requirement, specifying its type.
Docs: Omit

To improve https://github.com/conan-io/conan/issues/16784



Patch:
diff --git a/conans/model/graph_lock.py b/conans/model/graph_lock.py
index 999c57cc1..e3c3fa9dc 100644
--- a/conans/model/graph_lock.py
+++ b/conans/model/graph_lock.py
@@ -278,12 +278,15 @@ class Lockfile(object):
     def resolve_locked(self, node, require, resolve_prereleases):
         if require.build or node.context == CONTEXT_BUILD:
             locked_refs = self._build_requires.refs()
+            kind = "build_requires"
         elif node.is_conf:
             locked_refs = self._conf_requires.refs()
+            kind = "config_requires"
         else:
             locked_refs = self._requires.refs()
+            kind = "requires"
         try:
-            self._resolve(require, locked_refs, resolve_prereleases)
+            self._resolve(require, locked_refs, resolve_prereleases, kind)
         except ConanException:
             overrides = self._overrides.get(require.ref)
             if overrides is not None and len(overrides) > 1:
@@ -315,7 +318,7 @@ class Lockfile(object):
         if prevs:
             return prevs.get(node.package_id)
 
-    def _resolve(self, require, locked_refs, resolve_prereleases):
+    def _resolve(self, require, locked_refs, resolve_prereleases, kind):
         version_range = require.version_range
         ref = require.ref
         matches = [r for r in locked_refs if r.name == ref.name and r.user == ref.user and
@@ -327,7 +330,7 @@ class Lockfile(object):
                     break
             else:
                 if not self.partial:
-                    raise ConanException(f"Requirement '{ref}' not in lockfile")
+                    raise ConanException(f"Requirement '{ref}' not in lockfile '{kind}'")
         else:
             ref = require.ref
             if ref.revision is None:
@@ -337,10 +340,10 @@ class Lockfile(object):
                         break
                 else:
                     if not self.partial:
-                        raise ConanException(f"Requirement '{ref}' not in lockfile")
+                        raise ConanException(f"Requirement '{ref}' not in lockfile '{kind}'")
             else:
                 if ref not in matches and not self.partial:
-                    raise ConanException(f"Requirement '{repr(ref)}' not in lockfile")
+                    raise ConanException(f"Requirement '{repr(ref)}' not in lockfile '{kind}'")
 
     def replace_alias(self, require, alias):
         locked_alias = self._alias.get(alias)
@@ -352,4 +355,4 @@ class Lockfile(object):
 
     def resolve_locked_pyrequires(self, require, resolve_prereleases=None):
         locked_refs = self._python_requires.refs()  # CHANGE
-        self._resolve(require, locked_refs, resolve_prereleases)
+        self._resolve(require, locked_refs, resolve_prereleases, "python_requires")


Test patch:
diff --git a/test/integration/lockfile/test_lock_requires.py b/test/integration/lockfile/test_lock_requires.py
index 59736952b..d7db83083 100644
--- a/test/integration/lockfile/test_lock_requires.py
+++ b/test/integration/lockfile/test_lock_requires.py
@@ -102,7 +102,8 @@ def test_conanfile_txt_strict(requires):
     client.save({"consumer/conanfile.txt": f"[{requires}]\npkg/[>1.0]@user/testing"})
 
     client.run("install consumer/conanfile.txt", assert_error=True)
-    assert "Requirement 'pkg/[>1.0]@user/testing' not in lockfile" in client.out
+    kind = "build_requires" if requires == "tool_requires" else "requires"
+    assert f"Requirement 'pkg/[>1.0]@user/testing' not in lockfile '{kind}'" in client.out
 
     client.run("install consumer/conanfile.txt --lockfile-partial")
     assert "pkg/1.2@user/testing" in client.out