Repository: conan-io/conan

Issue:
Error message "printing with scope==virtual" after successfull package creation
For some of our sources a "conan create . user/channel" gives the following error after successfull creation of the conan package:

...

> ...
> RadioServerData/1.0.1.a1dfa37-0@fourbft/testing: Package 'b388ba0b0edd88e6e90419f7ea5b89302de61533' created
> RadioServerData/1.0.1.a1dfa37-0@fourbft/testing: Created package revision fee6c0874367d68fbbc44f64774b5b7d
> Traceback (most recent call last):
>  File "/usr/lib/python2.7/site-packages/conans/client/command.py", line 1579, in run
>    method(args[0][1:])
>  File "/usr/lib/python2.7/site-packages/conans/client/command.py", line 299, in create
>    test_build_folder=args.test_build_folder)
>  File "/usr/lib/python2.7/site-packages/conans/client/conan_api.py", line 93, in wrapper
>    return f(*args, **kwargs)
>  File "/usr/lib/python2.7/site-packages/conans/client/conan_api.py", line 389, in create
>    test_build_folder, test_folder, conanfile_path)
>  File "/usr/lib/python2.7/site-packages/conans/client/cmd/create.py", line 53, in create
>    keep_build=keep_build)
>  File "/usr/lib/python2.7/site-packages/conans/client/manager.py", line 80, in install
>    installer.install(deps_graph, keep_build)
>  File "/usr/lib/python2.7/site-packages/conans/client/installer.py", line 302, in install
>    self._build(nodes_by_level, keep_build, root_node, graph_info)
>  File "/usr/lib/python2.7/site-packages/conans/client/installer.py", line 327, in _build
>    self._propagate_info(root_node)
>  File "/usr/lib/python2.7/site-packages/conans/client/installer.py", line 436, in _propagate_info
>    conan_file.output.info("Applying build-requirement: %s" % str(n.ref))
>  File "/usr/lib/python2.7/site-packages/conans/client/output.py", line 80, in info
>    self.writeln(data, Color.BRIGHT_CYAN)
>  File "/usr/lib/python2.7/site-packages/conans/client/output.py", line 53, in writeln
>    self.write(data, front, back, True)
>  File "/usr/lib/python2.7/site-packages/conans/client/output.py", line 119, in write
>    assert self.scope != "virtual", "printing with scope==virtual"
>AssertionError: printing with scope==virtual
>
> ERROR: printing with scope==virtual

This happens with Conan version 1.14.4. This error does not occur with Conan 1.13.1.
OS is Linux using Python 2.7.6.

As I said above, it does only occur with some (few) of our packages. Might be related to a specific (common?) upstream package, but not sure. Couldn't nail it down any further, yet, but maybe you have an idea.



Discussion:
I've been trying different things but I'm not able to reproduce the error. It looks like you are calling `create` over a package that is also somewhere else in your dependency graph 😕 

I'll keep trying, but any hint will be really appreciated.

Thanks!
Hi @fourbft 

I have been checking the code too, and I can't see where this could happen. It would help to be able to reproduce it, if you don't want to post here private information, you could write to info@conan.io with further details. Thanks.
Related: https://github.com/conan-io/conan/pull/4987#issuecomment-487179864
Hi all, 
thanks for your input. Sorry, I was busy on another project in the meantime, but now I am back on this problem.
Yes, the hint to the related topic seems to lead somewhere: We have two "build_requires" in the problematic package, as well (googlemock and googletest). When I move them to real "requires" (i. e. put them in the "requirements( self)" function instead of "build_requirements( self)" and use self.requires instead of self.build_requires), the problem is gone.
Ok, another insight:
When I invert the order, in which I "build_require" googlemock and googletest, then the error disappears, too.
In our environment, googlemock requires (not build_requires) googletest.
If the problematic component above build_requires first googlemock and then googletest, I get the "printing with scope==virtual" error. When the problematic component first build_requires googletest and then googlemock, all is well.

Ok, could reproduce the bug with three trivial components (only conanfile.py files). (See attached tar.gz, untar, cd to conan_printing_with_scope_virtual_bug_demo and start build_CA_through_CC.sh script.)
When you invert the order of the build_requires in the component CC, the error is gone.
[conan_printing_with_scope_virtual_bug_demo.tar.gz](https://github.com/conan-io/conan/files/3127359/conan_printing_with_scope_virtual_bug_demo.tar.gz)

Thanks a lot for the example! There are a lot of tests, but no one like yours 😞. I've seen it is an issue related to _build requires_ when they are involved in diamond dependency, it also depends on the order of those build requires...

We'll try to fix it asap. Thanks again!

Resolving patch:
diff --git a/conans/client/graph/graph_builder.py b/conans/client/graph/graph_builder.py
--- a/conans/client/graph/graph_builder.py
+++ b/conans/client/graph/graph_builder.py
@@ -148,6 +148,9 @@ def _handle_require(self, name, node, require, dep_graph, check_updates, update,
             new_node.inverse_closure.add(node)
             node.public_deps[new_node.name] = new_node
 
+            # If the parent node is a build-require, this new node will be a build-require
+            # If the requirement is a build-require, this node will also be a build-require
+            new_node.build_require = node.build_require or require.build_require
             # New nodes will inherit the private property of its ancestor
             new_node.private = node.private or require.private
             if require.private or require.build_require:


Test patch:
diff --git a/conans/test/functional/build_requires/build_requires_test.py b/conans/test/functional/build_requires/build_requires_test.py
--- a/conans/test/functional/build_requires/build_requires_test.py
+++ b/conans/test/functional/build_requires/build_requires_test.py
@@ -6,6 +6,7 @@
 from conans.paths import CONANFILE
 from conans.test.utils.tools import TestClient
 from conans.util.files import load
+from conans.test.utils.conanfile import TestConanFile
 
 tool_conanfile = """from conans import ConanFile
 
@@ -50,6 +51,20 @@ def build_requirements(self):
 
 
 class BuildRequiresTest(unittest.TestCase):
+    def test_build_requires_diamond(self):
+        t = TestClient()
+        t.save({"conanfile.py": str(TestConanFile("libA", "0.1"))})
+        t.run("create . libA/0.1@user/testing")
+
+        t.save({"conanfile.py": str(TestConanFile("libB", "0.1",
+                                                  requires=["libA/0.1@user/testing"]))})
+        t.run("create . libB/0.1@user/testing")
+
+        t.save({"conanfile.py": str(TestConanFile("libC", "0.1",
+                                                  build_requires=["libB/0.1@user/testing",
+                                                                  "libA/0.1@user/testing"]))})
+        t.run("create . libC/0.1@user/testing")
+        self.assertIn("libC/0.1@user/testing: Created package", t.out)
 
     def create_with_tests_and_build_requires_test(self):
         client = TestClient()
diff --git a/conans/test/functional/graph/graph_manager_test.py b/conans/test/functional/graph/graph_manager_test.py
--- a/conans/test/functional/graph/graph_manager_test.py
+++ b/conans/test/functional/graph/graph_manager_test.py
@@ -768,7 +768,7 @@ def test_dont_conflict_private(self, private_first):
         self._check_node(liba2, "liba/0.2@user/testing#123", deps=[], build_deps=[],
                          dependents=[libc], closure=[])
 
-    def consecutive_private(self):
+    def test_consecutive_private(self):
         liba_ref = "liba/0.1@user/testing"
         libb_ref = "libb/0.1@user/testing"
         libc_ref = "libc/0.1@user/testing"