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

new build-order-prepare subcommand #13685

Closed
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
35 changes: 34 additions & 1 deletion conan/cli/commands/graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@
from conan.api.output import ConanOutput, cli_out_write, Color
from conan.cli import make_abs_path
from conan.cli.args import common_graph_args, validate_common_graph_args
from conan.cli.command import conan_command, conan_subcommand
from conan.cli.command import conan_command, conan_subcommand, OnceArgument
from conan.cli.formatters.graph import format_graph_html, format_graph_json, format_graph_dot
from conan.cli.formatters.graph.graph_info_text import format_graph_info
from conan.cli.printers.graph import print_graph_packages, print_graph_basic
from conan.internal.deploy import do_deploys
from conans.client.graph.install_graph import InstallGraph
from conan.errors import ConanException
from conans.model.graph_lock import Lockfile
from conans.model.recipe_ref import RecipeReference


@conan_command(group="Consumer")
Expand Down Expand Up @@ -83,6 +85,37 @@ def graph_build_order(conan_api, parser, subparser, *args):
return install_order_serialized


@conan_subcommand(formatters={"text": cli_out_write})
def graph_build_order_prepare(conan_api, parser, subparser, *args):
Copy link
Contributor

@czoido czoido Apr 14, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that maybe the name of the subcommand it's not so intuitive, what about something like:

  • conan graph install-prepare
  • conan graph install-config
    Maybe more explicit like this?
  • conan graph generate-install-args

"""
Compute the build order of a dependency graph.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be updated

"""
subparser.add_argument("build_order_file", help="build-order json file")
subparser.add_argument("ref", help="recipe to build")
subparser.add_argument("package_id", help="package to build")
Comment on lines +94 to +95
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couldn't we put this two arguments together so that you need to pass pkg/1.0:abc123? Your way is more explicit which might avoid confusion though..

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that is doable, whatever UI the team prefers.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I think I agree with adding the package_id in the reference too instead of a separate argument

subparser.add_argument("-l", "--lockfile", action=OnceArgument,
help="Path to a lockfile")
args = parser.parse_args(*args)

f = make_abs_path(args.build_order_file)
install_graph = InstallGraph.load(f)
ref = RecipeReference.loads(args.ref)
pkg = install_graph.find_build(ref, args.package_id)
context = pkg["context"]
cmd = f"--require={ref}" if context == "host" else f"--tool-require={ref}"
cmd += f" --build={ref}"
options = pkg["options"]
if options:
cmd += " " + " ".join(f"-o {o}" for o in options)

if args.lockfile:
lockfile_path = make_abs_path(args.lockfile)
graph_lock = Lockfile.load(lockfile_path)
# TODO: Replace here the overrides and save a new lockfile
cmd += f" --lockfile={args.lockfile}"
return cmd


@conan_subcommand(formatters={"text": cli_build_order, "json": json_build_order})
def graph_build_order_merge(conan_api, parser, subparser, *args):
"""
Expand Down
9 changes: 9 additions & 0 deletions conans/client/graph/install_graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,15 @@ def __init__(self, deps_graph=None):
if deps_graph is not None:
self._initialize_deps_graph(deps_graph)

def find_build(self, ref, package_id):
install_node = self._nodes.get(ref)
if install_node is None:
raise ConanException(f"Cannot find {ref} in build-order file")
packages = install_node.packages.get(package_id)
if packages is None:
raise ConanException(f"Cannot find {ref} - {package_id} in build-order file")
return packages.serialize()

@staticmethod
def load(filename):
data = json.loads(load(filename))
Expand Down
7 changes: 4 additions & 3 deletions conans/test/integration/lockfile/test_ci.py
Original file line number Diff line number Diff line change
Expand Up @@ -346,9 +346,10 @@ def test_single_config_decentralized(client_setup):
package_id = package["package_id"]
if binary != "Build":
continue
# TODO: The options are completely missing
c.run("install --requires=%s@ --build=%s@ --lockfile=app1_b_changed.lock -s os=Windows"
% (ref, ref))
c.run(f"graph build-order-prepare build_order.json {repr(ref)} {package_id} "
"--lockfile=app1_b_changed.lock")
cmd = c.stdout
c.run(f"install {cmd} -s os=Windows")
c.assert_listed_binary(
{str(ref): (package_id, "Build"),
"pkgawin/0.1": (pkgawin_01_id, "Cache"),
Expand Down