conans/client/graph/printer.py
from collections import OrderedDict
from conans.client.graph.graph import BINARY_SKIP, RECIPE_CONSUMER, RECIPE_VIRTUAL,\
RECIPE_EDITABLE
from conans.client.output import Color
from conans.model.ref import PackageReference
def _get_python_requires(conanfile):
result = set()
python_requires = getattr(conanfile, "python_requires", None)
if isinstance(python_requires, dict): # Old python requires
for _, py_require in python_requires.items():
result.add(py_require.ref)
result.update(_get_python_requires(py_require.conanfile))
elif python_requires:
result.update(conanfile.python_requires.all_refs())
return result
def print_graph(deps_graph, out):
requires = OrderedDict()
build_requires = OrderedDict()
python_requires = set()
build_time_nodes = deps_graph.build_time_nodes()
for node in sorted(deps_graph.nodes):
python_requires.update(_get_python_requires(node.conanfile))
if node.recipe in (RECIPE_CONSUMER, RECIPE_VIRTUAL):
continue
pref = PackageReference(node.ref, node.package_id)
if node in build_time_nodes: # TODO: May use build_require_context information
build_requires.setdefault(pref, []).append(node)
else:
requires.setdefault(pref, []).append(node)
out.writeln("Requirements", Color.BRIGHT_YELLOW)
def _recipes(nodes):
for _, list_nodes in nodes.items():
node = list_nodes[0] # For printing recipes, we can use the first one
if node.recipe == RECIPE_EDITABLE:
from_text = "from user folder"
else:
from_text = ("from local cache" if not node.remote
else "from '%s'" % node.remote.name)
out.writeln(" %s %s - %s" % (str(node.ref), from_text, node.recipe),
Color.BRIGHT_CYAN)
_recipes(requires)
if python_requires:
out.writeln("Python requires", Color.BRIGHT_YELLOW)
for p in python_requires:
out.writeln(" %s" % repr(p.copy_clear_rev()), Color.BRIGHT_CYAN)
out.writeln("Packages", Color.BRIGHT_YELLOW)
def _packages(nodes):
for package_id, list_nodes in nodes.items():
# The only way to have more than 1 states is to have 2
# and one is BINARY_SKIP (privates)
binary = set(n.binary for n in list_nodes)
if len(binary) > 1:
binary.remove(BINARY_SKIP)
assert len(binary) == 1
binary = binary.pop()
out.writeln(" %s - %s" % (str(package_id), binary), Color.BRIGHT_CYAN)
_packages(requires)
if build_requires:
out.writeln("Build requirements", Color.BRIGHT_YELLOW)
_recipes(build_requires)
out.writeln("Build requirements packages", Color.BRIGHT_YELLOW)
_packages(build_requires)
out.writeln("")