Skip to content

Commit

Permalink
Add different ref tracking syntax for <host_version> (conan-io#15274)
Browse files Browse the repository at this point in the history
* Use light=True where possible in build_requires tests

* Sketch for allowing tracking of different ref

* Add remote input to build-map command

* Update conans/client/graph/graph_builder.py

Co-authored-by: James <memsharded@gmail.com>

* Update conans/client/graph/graph_builder.py

Co-authored-by: James <memsharded@gmail.com>

* Update conans/client/graph/graph_builder.py

Co-authored-by: James <memsharded@gmail.com>

* Fix tests

---------

Co-authored-by: James <memsharded@gmail.com>
  • Loading branch information
AbrilRBS and memsharded authored Dec 15, 2023
1 parent 92af096 commit 9afacb4
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 3 deletions.
14 changes: 11 additions & 3 deletions conans/client/graph/graph_builder.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import copy
import os
import re
from collections import deque

from conans.client.conanfile.configure import run_configure_method
Expand All @@ -13,6 +14,7 @@
from conans.errors import ConanException
from conans.model.conan_file import ConanFile
from conans.model.options import Options
from conans.model.package_ref import PkgReference
from conans.model.recipe_ref import RecipeReference, ref_matches
from conans.model.requires import Requirement

Expand Down Expand Up @@ -270,14 +272,20 @@ def _resolve_replace_requires(self, node, require, profile_build, profile_host,
break # First match executes the alternative and finishes checking others

def _create_new_node(self, node, require, graph, profile_host, profile_build, graph_lock):
if require.ref.version == "<host_version>":
require_version = str(require.ref.version)
if require_version.startswith("<host_version") and require_version.endswith(">"):
if not require.build or require.visible:
raise ConanException(f"{node.ref} require '{require.ref}': 'host_version' can only "
"be used for non-visible tool_requires")
req = Requirement(require.ref, headers=True, libs=True, visible=True)
tracking_ref = require_version.split(':', 1)
ref = require.ref
if len(tracking_ref) > 1:
ref = RecipeReference.loads(str(node.ref))
ref.name = tracking_ref[1][:-1] # Remove the trailing >
req = Requirement(ref, headers=True, libs=True, visible=True)
transitive = node.transitive_deps.get(req)
if transitive is None:
raise ConanException(f"{node.ref} require '{require.ref}': didn't find a matching "
raise ConanException(f"{node.ref} require '{ref}': didn't find a matching "
"host dependency")
require.ref.version = transitive.require.ref.version

Expand Down
22 changes: 22 additions & 0 deletions conans/test/integration/build_requires/build_requires_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -512,6 +512,28 @@ def test_overriden_host_version_transitive_deps(self):
c.run("install app --lockfile=app/conan.lock")
c.assert_listed_require({"protobuf/1.1": "Cache"}, build=True)

@pytest.mark.parametrize("host_version, assert_error, assert_msg", [
("libgettext>", False, "gettext/0.2#d9f9eaeac9b6e403b271f04e04149df2"),
# Error cases, just checking that we fail gracefully - no tracebacks
("libgettext", True, "Package 'gettext/<host_version:libgettext' not resolved"),
(":>", True, "app/1.0 require ':/1.0': didn't find a matching host dependency"),
(">", True, "app/1.0 require '/1.0': didn't find a matching host dependency"),
(":", True, " Package 'gettext/<host_version::' not resolved"),
("", True, "Package 'gettext/<host_version:' not resolved: No remote defined")
])
def test_host_version_different_ref(self, host_version, assert_error, assert_msg):
tc = TestClient(light=True)
tc.save({"gettext/conanfile.py": GenConanfile("gettext"),
"libgettext/conanfile.py": GenConanfile("libgettext"),
"app/conanfile.py": GenConanfile("app", "1.0").with_requires("libgettext/[>0.1]")
.with_tool_requirement(f"gettext/<host_version:{host_version}")})
tc.run("create libgettext --version=0.2")
tc.run("create gettext --version=0.1 --build-require")
tc.run("create gettext --version=0.2 --build-require")

tc.run("create app", assert_error=assert_error)
assert assert_msg in tc.out


def test_build_missing_build_requires():
c = TestClient()
Expand Down

0 comments on commit 9afacb4

Please sign in to comment.