Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix trait visible for build requires #15357

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion conans/model/requires.py
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ def transform_downstream(self, pkg_type, require, dep_pkg_type):
if require.build: # public!
# TODO: To discuss if this way of conflicting build_requires is actually useful or not
downstream_require = Requirement(require.ref, headers=False, libs=False, build=True,
run=False, visible=True, direct=False)
run=False, visible=self.visible, direct=False)
return downstream_require

if self.build: # Build-requires
Expand Down
62 changes: 62 additions & 0 deletions conans/test/integration/graph/core/graph_manager_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -1138,6 +1138,68 @@ def test_d_b_header_only_transitive_headers_b(self):
(libb, True, False, False, False),
(liba, True, True, False, False)])

def test_visible_transitivity(self):
# app -> libd/0.1 -> libc/0.1 -(visible=False)-> libb0.1 -> liba0.1
self.recipe_conanfile("liba/0.1", GenConanfile())
self.recipe_conanfile("libb/0.1", GenConanfile().with_requirement("liba/0.1"))
self.recipe_conanfile("libc/0.1", GenConanfile().with_requirement("libb/0.1",
visible=False))
self.recipe_conanfile("libd/0.1", GenConanfile().with_requirement("libc/0.1"))
consumer = self.recipe_consumer("app/0.1", ["libd/0.1"])

deps_graph = self.build_consumer(consumer)

self.assertEqual(5, len(deps_graph.nodes))
app = deps_graph.root
libd = app.dependencies[0].dst
libc = libd.dependencies[0].dst
libb = libc.dependencies[0].dst
liba = libb.dependencies[0].dst

self._check_node(app, "app/0.1", deps=[libd])
self._check_node(libd, "libd/0.1#123", deps=[libc], dependents=[app])
self._check_node(libc, "libc/0.1#123", deps=[libb], dependents=[libd])
self._check_node(libb, "libb/0.1#123", deps=[liba], dependents=[libc])
self._check_node(liba, "liba/0.1#123", dependents=[libb])

# node, headers, lib, build, run
_check_transitive(app, [(libd, True, True, False, False),
(libc, True, True, False, False)])
_check_transitive(libd, [(libc, True, True, False, False)])
_check_transitive(libc, [(libb, True, True, False, False),
(liba, True, True, False, False)])

def test_visible_build_transitivity(self):
# app -> libd/0.1 -> libc/0.1 -(visible=True, build=True)-> libb0.1 -> liba0.1
self.recipe_conanfile("liba/0.1", GenConanfile())
self.recipe_conanfile("libb/0.1", GenConanfile().with_requirement("liba/0.1"))
self.recipe_conanfile("libc/0.1", GenConanfile().with_requirement("libb/0.1", build=True))
self.recipe_conanfile("libd/0.1", GenConanfile().with_requirement("libc/0.1"))
consumer = self.recipe_consumer("app/0.1", ["libd/0.1"])

deps_graph = self.build_consumer(consumer)

self.assertEqual(5, len(deps_graph.nodes))
app = deps_graph.root
libd = app.dependencies[0].dst
libc = libd.dependencies[0].dst
libb = libc.dependencies[0].dst
liba = libb.dependencies[0].dst

self._check_node(app, "app/0.1", deps=[libd])
self._check_node(libd, "libd/0.1#123", deps=[libc], dependents=[app])
self._check_node(libc, "libc/0.1#123", deps=[libb], dependents=[libd])
self._check_node(libb, "libb/0.1#123", deps=[liba], dependents=[libc])
self._check_node(liba, "liba/0.1#123", dependents=[libb])

# node, headers, lib, build, run
_check_transitive(app, [(libd, True, True, False, False),
(libc, True, True, False, False),
(libb, False, False, True, False)])
_check_transitive(libd, [(libc, True, True, False, False),
(libb, False, False, True, False)])
_check_transitive(libc, [(libb, True, True, True, False)])


class TestLinearFiveLevelsLibraries(GraphManagerTest):
def test_all_static(self):
Expand Down
26 changes: 26 additions & 0 deletions conans/test/integration/graph/core/test_build_requires.py
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,32 @@ def test_build_require_conflict(self):
self._check_node(grass2, "grass/0.2#123", dependents=[cheetah])


class TestBuildRequiresVisible(GraphManagerTest):

def test_visible_build(self):
self._cache_recipe("liba/0.1", GenConanfile())
self._cache_recipe("libb/0.1", GenConanfile().with_requirement("liba/0.1", build=True))
self._cache_recipe("libc/0.1", GenConanfile().with_requirement("libb/0.1", visible=False))
deps_graph = self.build_graph(GenConanfile("app", "0.1").with_require("libc/0.1"))

self.assertEqual(4, len(deps_graph.nodes))
app = deps_graph.root
libc = app.dependencies[0].dst
libb = libc.dependencies[0].dst
liba = libb.dependencies[0].dst

self._check_node(app, "app/0.1@", deps=[libc], dependents=[])
self._check_node(libc, "libc/0.1#123", deps=[libb], dependents=[app])
self._check_node(libb, "libb/0.1#123", deps=[liba], dependents=[libc])
self._check_node(liba, "liba/0.1#123", deps=[], dependents=[libb])

# node, include, link, build, run
_check_transitive(app, [(libc, True, True, False, False)])
_check_transitive(libc, [(libb, True, True, False, False),
(liba, False, False, True, False)]) # liba is build & visible!
_check_transitive(libb, [(liba, True, True, True, False)])


class TestTestRequire(GraphManagerTest):

def test_basic(self):
Expand Down
2 changes: 1 addition & 1 deletion conans/test/integration/graph/test_dependencies_visit.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ def generate(self):
False, "=>zlib/0.1"),
('print("=>{}".format(self.dependencies.get("zlib", build=False).ref))',
False, "=>zlib/0.2"),
('print("=>{}".format(self.dependencies.get("zlib", build=True, visible=True).ref))',
('print("=>{}".format(self.dependencies.get("zlib", build=True, visible=False).ref))',
False, "=>zlib/0.1"),
('self.dependencies.get("cmake", build=True)', True,
'There are more than one requires matching the specified filters: {\'build\': True}\n'
Expand Down
16 changes: 16 additions & 0 deletions conans/test/integration/graph/test_skip_binaries.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,3 +178,19 @@ def test_skipped_intermediate_header():
# liba brings only libraries
assert "set(liba_INCLUDE_DIRS_RELEASE )" in liba_data
assert "set(liba_LIBS_RELEASE liba)" in liba_data


def test_skip_visible_build():
# https://github.com/conan-io/conan/issues/15346
c = TestClient()
c.save({"liba/conanfile.py": GenConanfile("liba", "0.1"),
"libb/conanfile.py": GenConanfile("libb", "0.1").with_requirement("liba/0.1",
build=True),
"libc/conanfile.py": GenConanfile("libc", "0.1").with_requirement("libb/0.1",
visible=False),
"app/conanfile.py": GenConanfile("app", "0.1").with_requires("libc/0.1")})
c.run("create liba")
c.run("create libb")
c.run("create libc")
c.run("install app --format=json")
assert re.search(r"Skipped binaries(\s*)libb/0.1, liba/0.1", c.out)