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

Refactor/build order serialize #15602

Merged
merged 2 commits into from
Feb 6, 2024
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
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