From bc6a0eb13b2d0f82703464c77faf1df3640401aa Mon Sep 17 00:00:00 2001 From: James Date: Mon, 6 Mar 2023 18:30:03 +0100 Subject: [PATCH] export-pkg remote improvements (#13324) * export-pkg remote improvements * review --- conan/cli/commands/export_pkg.py | 23 +++++++--- conan/cli/commands/install.py | 1 - .../integration/command/export_pkg_test.py | 44 +++++++++---------- 3 files changed, 40 insertions(+), 28 deletions(-) diff --git a/conan/cli/commands/export_pkg.py b/conan/cli/commands/export_pkg.py index d71f6bc425e..1181efa2b73 100644 --- a/conan/cli/commands/export_pkg.py +++ b/conan/cli/commands/export_pkg.py @@ -27,6 +27,13 @@ def export_pkg(conan_api, parser, *args): parser.add_argument("-tf", "--test-folder", action=OnceArgument, help='Alternative test folder name. By default it is "test_package". ' 'Use "" to skip the test stage') + parser.add_argument("-sb", "--skip-binaries", action="store_true", + help="Skip installing dependencies binaries") + group = parser.add_mutually_exclusive_group() + group.add_argument("-r", "--remote", action="append", default=None, + help='Look in the specified remote or remotes server') + group.add_argument("-nr", "--no-remote", action="store_true", + help='Do not use remote, resolve exclusively in the cache') add_reference_args(parser) add_lockfile_args(parser) @@ -39,6 +46,7 @@ def export_pkg(conan_api, parser, *args): lockfile = conan_api.lockfile.get_lockfile(lockfile=args.lockfile, conanfile_path=path, cwd=cwd, partial=args.lockfile_partial) profile_host, profile_build = conan_api.profiles.get_profiles_from_args(args) + remotes = conan_api.remotes.list(args.remote) if not args.no_remote else [] ref, conanfile = conan_api.export.export(path=path, name=args.name, version=args.version, user=args.user, channel=args.channel, lockfile=lockfile) @@ -52,20 +60,25 @@ def export_pkg(conan_api, parser, *args): ref.name, ref.version, ref.user, ref.channel, profile_host=profile_host, profile_build=profile_build, - lockfile=lockfile, remotes=None, update=None, + lockfile=lockfile, remotes=remotes, update=None, is_build_require=args.build_require) print_graph_basic(deps_graph) deps_graph.report_graph_error() - conan_api.graph.analyze_binaries(deps_graph, build_mode=[ref.name], lockfile=lockfile) + conan_api.graph.analyze_binaries(deps_graph, build_mode=[ref.name], lockfile=lockfile, + remotes=remotes) deps_graph.report_graph_error() root_node = deps_graph.root root_node.ref = ref - # It is necessary to install binaries, in case there are build_requires necessary to export - # But they should be local, if this was built here - conan_api.install.install_binaries(deps_graph=deps_graph, remotes=None) + if not args.skip_binaries: + # unless the user explicitly opts-out with --skip-binaries, it is necessary to install + # binaries, in case there are build_requires necessary to export, like tool-requires=cmake + # and package() method doing ``cmake.install()`` + # for most cases, deps would be in local cache already because of a previous "conan install" + # but if it is not the case, the binaries from remotes will be downloaded + conan_api.install.install_binaries(deps_graph=deps_graph, remotes=remotes) source_folder = os.path.dirname(path) output_folder = make_abs_path(args.output_folder, cwd) if args.output_folder else None conan_api.install.install_consumer(deps_graph=deps_graph, source_folder=source_folder, diff --git a/conan/cli/commands/install.py b/conan/cli/commands/install.py index e87190d18c2..6ea2685ac56 100644 --- a/conan/cli/commands/install.py +++ b/conan/cli/commands/install.py @@ -7,7 +7,6 @@ from conan.cli import make_abs_path from conan.cli.printers import print_profiles from conan.cli.printers.graph import print_graph_packages, print_graph_basic -from conan.errors import ConanException def json_install(info): diff --git a/conans/test/integration/command/export_pkg_test.py b/conans/test/integration/command/export_pkg_test.py index 0a161d41827..d63b2fdb055 100644 --- a/conans/test/integration/command/export_pkg_test.py +++ b/conans/test/integration/command/export_pkg_test.py @@ -26,28 +26,23 @@ def test_dont_touch_server(self): def test_transitive_without_settings(self): # https://github.com/conan-io/conan/issues/3367 client = TestClient() - client.save({CONANFILE: GenConanfile()}) - client.run("create . --name=pkgc --version=0.1 --user=user --channel=testing") - conanfile = """from conan import ConanFile -class PkgB(ConanFile): - settings = "arch" - requires = "pkgc/0.1@user/testing" -""" - client.save({CONANFILE: conanfile}) - client.run("create . --name=pkgb --version=0.1 --user=user --channel=testing") - conanfile = """from conan import ConanFile -class PkgA(ConanFile): - requires = "pkgb/0.1@user/testing" - def build(self): - self.output.info("BUILDING PKGA") -""" - client.save({CONANFILE: conanfile}) - client.run("build . -bf=build") - client.run("export-pkg . --name=pkga --version=0.1 --user=user --channel=testing " - "-pr=default") + client.save({"pkgc/conanfile.py": GenConanfile("pkgc", "0.1"), + "pkgb/conanfile.py": GenConanfile("pkgb", "0.1").with_requires("pkgc/0.1"), + "pkga/conanfile.py": GenConanfile("pkga", "0.1").with_requires("pkgb/0.1")}) + client.run("create pkgc") + client.run("create pkgb") + + client.run("build pkga -bf=build") + client.run("export-pkg pkga ") package_id = re.search(r"Packaging to (\S+)", str(client.out)).group(1) - self.assertIn(f"conanfile.py (pkga/0.1@user/testing): " - f"Package '{package_id}' created", client.out) + self.assertIn(f"conanfile.py (pkga/0.1): Package '{package_id}' created", client.out) + + # we can export-pkg without the dependencies binaries if we need to optimize + client.run("remove pkgc*:* -c") + client.run("remove pkgb*:* -c") + client.run("export-pkg pkga --skip-binaries") + package_id = re.search(r"Packaging to (\S+)", str(client.out)).group(1) + self.assertIn(f"conanfile.py (pkga/0.1): Package '{package_id}' created", client.out) def test_package_folder_errors(self): # https://github.com/conan-io/conan/issues/2350 @@ -493,7 +488,7 @@ def test_export_pkg_tool_requires(): - to inject the tool-requirements - to propagate the environment and the conf """ - c = TestClient() + c = TestClient(default_server_user=True) tool = textwrap.dedent(""" from conan import ConanFile class Tool(ConanFile): @@ -523,6 +518,11 @@ def package(self): c.run("export-pkg consumer") assert "conanfile.py (consumer/0.1): MYCONF CONF_VALUE" in c.out assert "MYVAR=MYVALUE" in c.out + c.run("upload tool* -r=default -c") + c.run("remove tool* -c") + c.run("export-pkg consumer") + assert "conanfile.py (consumer/0.1): MYCONF CONF_VALUE" in c.out + assert "MYVAR=MYVALUE" in c.out def test_export_pkg_output_folder():