Skip to content

Commit 658260f

Browse files
AbrilRBSmemsharded
andauthored
Fix assert when finding compatible binaries of a package that exists in both contexts with different settings (#19208)
* Add failing test for compat when different context reuires different packages potential path forward What? Maybe simplify test make test valid in windows too Bump version * This also fails with update * fixes * fixes * Simplify --------- Co-authored-by: memsharded <[email protected]>
1 parent 13d5e91 commit 658260f

File tree

3 files changed

+68
-5
lines changed

3 files changed

+68
-5
lines changed

conan/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22
from conan.internal.model.workspace import Workspace
33
from conan.internal.model.version import Version
44

5-
__version__ = '2.22.1'
5+
__version__ = '2.22.2'
66
conan_version = Version(__version__)

conan/internal/graph/graph_binaries.py

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -164,8 +164,17 @@ def _compatible_find_existing_binaries(self, node, compatibles, remotes, update)
164164
for package_id, compatible_package in compatibles.items():
165165
node._package_id = package_id # Modifying package id under the hood, FIXME
166166
node.binary = None # Invalidate it
167+
# Check that this same reference hasn't already been checked
168+
if self._evaluate_is_cached(node):
169+
# If we have already processed this compatible pref,
170+
# mark it as usable based on previous evaluation
171+
if node.binary in (BINARY_CACHE, BINARY_DOWNLOAD):
172+
self._compatible_found(conanfile, package_id, compatible_package)
173+
return
167174
cache_latest_prev = self._compatible_cache_latest_prev(node) # not check remotes
168175
if cache_latest_prev:
176+
# If we have binary info, it means that the package was already processed,
177+
# and we got a hit from the cache of compatibles
169178
self._binary_in_cache(node, cache_latest_prev)
170179
self._compatible_found(conanfile, package_id, compatible_package)
171180
return
@@ -186,6 +195,13 @@ def _compatible_find_existing_binaries(self, node, compatibles, remotes, update)
186195
f"{conanfile.info.dump_diff(compatible_package)}")
187196
node._package_id = package_id # Modifying package id under the hood, FIXME
188197
node.binary = None # Invalidate it
198+
199+
if self._evaluate_is_cached(node):
200+
# If we have already processed this compatible pref,
201+
# mark it as usable based on previous evaluation
202+
if node.binary in (BINARY_CACHE, BINARY_DOWNLOAD, BINARY_UPDATE):
203+
self._compatible_found(conanfile, package_id, compatible_package)
204+
return
189205
cache_latest_prev = self._compatible_cache_latest_prev(node) # Not check remotes
190206
if cache_latest_prev:
191207
self._evaluate_cache_update(cache_latest_prev, node, remotes, update)
@@ -203,10 +219,6 @@ def _compatible_cache_latest_prev(self, node):
203219
""" simplified checking of compatible_packages, that should be found existing, but
204220
will never be built, for example. They cannot be editable either at this point.
205221
"""
206-
# Check that this same reference hasn't already been checked
207-
if self._evaluate_is_cached(node):
208-
return
209-
210222
# TODO: Test that this works
211223
if node.conanfile.info.invalid:
212224
node.binary = BINARY_INVALID

test/integration/package_id/compatible_test.py

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
import json
22
import textwrap
33

4+
import pytest
5+
6+
from conan.test.utils.env import environment_update
47
from conan.test.utils.tools import TestClient, GenConanfile
58

69

@@ -768,3 +771,51 @@ def no_cppstd_compat(conanfile):
768771
# Now we try again, this time app will find the compatible dep without cppstd
769772
tc.run("install --requires=dep/1.0 -pr=profile -s=compiler.cppstd=17")
770773
assert f"dep/1.0: Found compatible package '{dep_package_id}'" in tc.out
774+
775+
776+
@pytest.mark.parametrize("from_remote", [True, False])
777+
@pytest.mark.parametrize("update", [True, False])
778+
def test_compatibility_different_settings_per_context(from_remote, update):
779+
tc = TestClient(default_server_user=True)
780+
tc.save({"protobuf/conanfile.py": GenConanfile("protobuf", "1.0")
781+
.with_settings("compiler"),
782+
"conanfile.py": GenConanfile("consumer", "1.0")
783+
.with_require("protobuf/1.0")
784+
.with_tool_requires("protobuf/1.0")
785+
})
786+
tc.run("create protobuf -s=compiler.cppstd=14")
787+
if from_remote:
788+
tc.run("upload * -r=default -c")
789+
tc.run("remove * -c")
790+
update_arg = "--update" if update else ""
791+
tc.run(f"install . -s=compiler.cppstd=14 -s:b=compiler.cppstd=17 --build=missing {update_arg}")
792+
793+
794+
@pytest.mark.parametrize("update", [True, False])
795+
def test_compatibility_different_settings_per_context_prevs(update):
796+
tc = TestClient(default_server_user=True)
797+
proto = GenConanfile("protobuf", "1.0").with_settings("compiler")
798+
proto.with_package_file("file.txt", env_var="MY_VAR")
799+
consumer = GenConanfile().with_requires("protobuf/1.0").with_tool_requires("protobuf/1.0")
800+
tc.save({"protobuf/conanfile.py": proto,
801+
"conanfile.py": consumer})
802+
803+
settings = "-s:a compiler=gcc -s:a compiler.version=9 -s:a compiler.libcxx=libstdc++"
804+
with environment_update({"MY_VAR": "value"}):
805+
tc.run(f"create protobuf {settings} -s=compiler.cppstd=14")
806+
tc.run("upload * -r=default -c")
807+
808+
tc2 = TestClient(servers=tc.servers)
809+
tc2.save({"conanfile.py": consumer})
810+
update_arg = "--update" if update else ""
811+
tc2.run(f"install . {settings} -s=compiler.cppstd=14 -s:b=compiler.cppstd=17 {update_arg}")
812+
tc2.assert_listed_binary({"protobuf/1.0": ("36d978cbb4dc35906d0fd438732d5e17cd1e388d",
813+
"Download (default)")})
814+
815+
with environment_update({"MY_VAR": "value2"}):
816+
tc.run(f"create protobuf {settings} -s=compiler.cppstd=14")
817+
tc.run("upload * -r=default -c")
818+
tc2.run(f"install . {settings} -s=compiler.cppstd=14 -s:b=compiler.cppstd=17 {update_arg}")
819+
origin = "Cache" if not update else "Update (default)"
820+
tc2.assert_listed_binary({"protobuf/1.0": ("36d978cbb4dc35906d0fd438732d5e17cd1e388d",
821+
origin)})

0 commit comments

Comments
 (0)