Skip to content

Commit

Permalink
Refactor/build order serialize (#15602)
Browse files Browse the repository at this point in the history
* refactor for build-order serialized output

* check test
  • Loading branch information
memsharded authored Feb 6, 2024
1 parent 07d49a5 commit 81d816f
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 14 deletions.
11 changes: 9 additions & 2 deletions conan/cli/commands/graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ def graph(conan_api, parser, *args):

def cli_build_order(build_order):
# TODO: Very simple cli output, probably needs to be improved
build_order = build_order["order"] if isinstance(build_order, dict) else build_order
for level in build_order:
for item in level:
# If this is a configuration order, it has no packages entry, each item is a package
Expand All @@ -60,14 +61,16 @@ def graph_build_order(conan_api, parser, subparser, *args):
Compute the build order of a dependency graph.
"""
common_graph_args(subparser)
subparser.add_argument("--order", choices=['recipe', 'configuration'], default="recipe",
subparser.add_argument("--order-by", choices=['recipe', 'configuration'],
help='Select how to order the output, "recipe" by default if not set.')
args = parser.parse_args(*args)

# parameter validation
if args.requires and (args.name or args.version or args.user or args.channel):
raise ConanException("Can't use --name, --version, --user or --channel arguments with "
"--requires")
if args.order_by is None:
ConanOutput().warning("Please specify --order-by argument", warn_tag="deprecated")

cwd = os.getcwd()
path = conan_api.local.get_conanfile_path(args.path, cwd, py=None) if args.path else None
Expand Down Expand Up @@ -99,8 +102,10 @@ def graph_build_order(conan_api, parser, subparser, *args):

out = ConanOutput()
out.title("Computing the build order")
install_graph = InstallGraph(deps_graph, order=args.order)
install_graph = InstallGraph(deps_graph, order_by=args.order_by)
install_order_serialized = install_graph.install_build_order()
if args.order_by is None: # legacy
install_order_serialized = install_order_serialized["order"]

lockfile = conan_api.lockfile.update_lockfile(lockfile, deps_graph, args.lockfile_packages,
clean=args.lockfile_clean)
Expand All @@ -125,6 +130,8 @@ def graph_build_order_merge(conan_api, parser, subparser, *args):
result.merge(install_graph)

install_order_serialized = result.install_build_order()
if getattr(result, "legacy"):
install_order_serialized = install_order_serialized["order"]
return install_order_serialized


Expand Down
20 changes: 10 additions & 10 deletions conans/client/graph/install_graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -306,10 +306,11 @@ class InstallGraph:
""" A graph containing the package references in order to be built/downloaded
"""

def __init__(self, deps_graph, order="recipe"):
def __init__(self, deps_graph, order_by=None):
self._nodes = {} # ref with rev: _InstallGraphNode
self._order = order
self._node_cls = _InstallRecipeReference if order == "recipe" else _InstallConfiguration
order_by = order_by or "recipe"
self._order = order_by
self._node_cls = _InstallRecipeReference if order_by == "recipe" else _InstallConfiguration
self._is_test_package = False
if deps_graph is not None:
self._initialize_deps_graph(deps_graph)
Expand Down Expand Up @@ -338,12 +339,10 @@ def merge(self, other):

@staticmethod
def deserialize(data, filename):
# Automatic deduction of the order based on the data
try:
order = "recipe" if "packages" in data[0][0] else "configuration"
except IndexError:
order = "recipe"
result = InstallGraph(None, order=order)
legacy = isinstance(data, list)
order, data = ("recipe", data) if legacy else (data["order_by"], data["order"])
result = InstallGraph(None, order_by=order)
result.legacy = legacy
for level in data:
for item in level:
elem = result._node_cls.deserialize(item, filename)
Expand Down Expand Up @@ -390,7 +389,8 @@ def install_build_order(self):
This is basically a serialization of the build-order
"""
install_order = self.install_order()
result = [[n.serialize() for n in level] for level in install_order]
result = {"order_by": self._order,
"order": [[n.serialize() for n in level] for level in install_order]}
return result

def raise_errors(self):
Expand Down
11 changes: 9 additions & 2 deletions conans/test/integration/command_v2/test_info_build_order.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,11 @@ def test_info_build_order():

assert bo_json == result

c.run("graph build-order consumer --order-by=recipe --build=missing --format=json")
bo_json = json.loads(c.stdout)
assert bo_json["order_by"] == "recipe"
assert bo_json["order"] == result


def test_info_build_order_configuration():
c = TestClient()
Expand All @@ -71,6 +76,7 @@ def test_info_build_order_configuration():
c.run("export pkg --name=pkg --version=0.1")
c.run("graph build-order consumer --build=missing --order=configuration --format=json")
bo_json = json.loads(c.stdout)
assert bo_json["order_by"] == "configuration"

result = [
[
Expand Down Expand Up @@ -108,7 +114,7 @@ def test_info_build_order_configuration():
]
]

assert bo_json == result
assert bo_json["order"] == result


def test_info_build_order_configuration_text_formatter():
Expand Down Expand Up @@ -333,6 +339,7 @@ def test_info_build_order_merge_multi_product_configurations():
redirect_stdout="bo3.json")

bo_json = json.loads(c.load("bo3.json"))
assert bo_json["order_by"] == "configuration"
result = [
[
{
Expand Down Expand Up @@ -390,7 +397,7 @@ def test_info_build_order_merge_multi_product_configurations():
]
]

assert bo_json == result
assert bo_json["order"] == result


def test_info_build_order_merge_conditionals():
Expand Down

0 comments on commit 81d816f

Please sign in to comment.