Skip to content

Commit

Permalink
fix requires(..., package_id_mode=) with diamonds (#16987)
Browse files Browse the repository at this point in the history
  • Loading branch information
memsharded authored Sep 24, 2024
1 parent eaf7696 commit 2794417
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 3 deletions.
3 changes: 2 additions & 1 deletion conans/model/info.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ def __init__(self, ref, package_id, default_package_id_mode):
try:
func_package_id_mode = getattr(self, default_package_id_mode)
except AttributeError:
raise ConanException("'%s' is not a known package_id_mode" % default_package_id_mode)
raise ConanException(f"require {self._ref} package_id_mode='{default_package_id_mode}' "
"is not a known package_id_mode")
else:
func_package_id_mode()

Expand Down
5 changes: 4 additions & 1 deletion conans/model/requires.py
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,10 @@ def aggregate(self, other):
self.transitive_libs = self.transitive_libs or other.transitive_libs
if not other.test:
self.test = False # it it was previously a test, but also required by non-test
# TODO: self.package_id_mode => Choose more restrictive?
# package_id_mode is not being propagated downstream. So it is enough to check if the
# current require already defined it or not
if self.package_id_mode is None:
self.package_id_mode = other.package_id_mode

def transform_downstream(self, pkg_type, require, dep_pkg_type):
"""
Expand Down
85 changes: 84 additions & 1 deletion test/integration/package_id/package_id_requires_modes_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ class TestPackageIDRequirementsModes:
[("unrelated_mode", "2.0", "", ""),
("patch_mode", "1.0.0.1", "1.0.1", "1.0.1"),
("minor_mode", "1.0.1", "1.2", "1.2.Z"),
("minor_mode", "1.0.1", "1.2", "1.2.Z"),
("major_mode", "1.5", "2.0", "2.Y.Z"),
("semver_mode", "1.5", "2.0", "2.Y.Z"),
("full_mode", "1.0", "1.0.0.1", "1.0.0.1")])
Expand Down Expand Up @@ -110,3 +109,87 @@ def package_id(self):
self.assertIn("dep2/1.0@user/testing: PkgNames: ['dep1']", client.out)
self.assertIn("consumer/1.0@user/testing: PKGNAMES: ['dep1', 'dep2']", client.out)
self.assertIn("consumer/1.0@user/testing: Created", client.out)


class TestRequirementPackageId:
""" defining requires(..., package_id_mode)
"""

@pytest.mark.parametrize("mode, pattern",
[("patch_mode", "1.2.3"),
("minor_mode", "1.2.Z"),
("major_mode", "1.Y.Z")])
def test(self, mode, pattern):
c = TestClient(light=True)
pkg = GenConanfile("pkg", "0.1").with_requirement("dep/1.2.3", package_id_mode=mode)
c.save({"dep/conanfile.py": GenConanfile("dep", "1.2.3"),
"pkg/conanfile.py": pkg})
c.run("create dep")
c.run("create pkg")
c.run("list pkg:*")
assert f"dep/{pattern}" in c.out

def test_wrong_mode(self):
c = TestClient(light=True)
pkg = GenConanfile("pkg", "0.1").with_requirement("dep/1.2.3", package_id_mode="nothing")
c.save({"dep/conanfile.py": GenConanfile("dep", "1.2.3"),
"pkg/conanfile.py": pkg})
c.run("create dep")
c.run("create pkg", assert_error=True)
assert "ERROR: require dep/1.2.3 package_id_mode='nothing' is not a known package_id_mode" \
in c.out

@pytest.mark.parametrize("mode, pattern",
[("patch_mode", "1.2.3"),
("minor_mode", "1.2.Z"),
("major_mode", "1.Y.Z")])
def test_half_diamond(self, mode, pattern):
# pkg -> libb -> liba
# \----(mode)----/
c = TestClient(light=True)
pkg = GenConanfile("pkg", "0.1").with_requirement("liba/1.2.3", package_id_mode=mode)\
.with_requirement("libb/1.2.3")
c.save({"liba/conanfile.py": GenConanfile("liba", "1.2.3"),
"libb/conanfile.py": GenConanfile("libb", "1.2.3").with_requires("liba/1.2.3"),
"pkg/conanfile.py": pkg})
c.run("create liba")
c.run("create libb")
c.run("create pkg")
c.run("list pkg:*")
assert f"liba/{pattern}" in c.out
# reverse order also works the same
pkg = GenConanfile("pkg", "0.1").with_requirement("libb/1.2.3")\
.with_requirement("liba/1.2.3", package_id_mode=mode)
c.save({"pkg/conanfile.py": pkg})
c.run("create pkg")
c.run("list pkg:*")
assert f"liba/{pattern}" in c.out

@pytest.mark.parametrize("mode, pattern",
[("patch_mode", "1.2.3"),
("minor_mode", "1.2.Z"),
("major_mode", "1.Y.Z")])
def test_half_diamond_conflict(self, mode, pattern):
# pkg -> libb --(mode)-> liba
# \----(mode)-----------/
# The libb->liba mode is not propagated down to pkg, so it doesn't really conflict
c = TestClient(light=True)
pkg = GenConanfile("pkg", "0.1").with_requirement("liba/1.2.3", package_id_mode=mode) \
.with_requirement("libb/1.2.3")
libb = GenConanfile("libb", "1.2.3").with_requirement("liba/1.2.3",
package_id_mode="patch_mode")
c.save({"liba/conanfile.py": GenConanfile("liba", "1.2.3"),
"libb/conanfile.py": libb,
"pkg/conanfile.py": pkg})
c.run("create liba")
c.run("create libb")
c.run("create pkg")
c.run("list pkg:*")
assert f"liba/{pattern}" in c.out
# reverse order also works the same
pkg = GenConanfile("pkg", "0.1").with_requirement("libb/1.2.3") \
.with_requirement("liba/1.2.3", package_id_mode=mode)
c.save({"pkg/conanfile.py": pkg})
c.run("create pkg")
c.run("list pkg:*")
assert f"liba/{pattern}" in c.out

0 comments on commit 2794417

Please sign in to comment.