From 45dc7aebee975aebeb5367756bc6c5b15106a4f2 Mon Sep 17 00:00:00 2001 From: memsharded Date: Mon, 29 Aug 2022 20:02:03 +0200 Subject: [PATCH 1/3] fix deployers not creating output_folder --- conan/api/subapi/install.py | 8 ++++-- .../functional/command/test_install_deploy.py | 28 +++++++++++++++++-- 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/conan/api/subapi/install.py b/conan/api/subapi/install.py index 7b865ae2e72..8fbfd177f6d 100644 --- a/conan/api/subapi/install.py +++ b/conan/api/subapi/install.py @@ -7,7 +7,7 @@ from conans.client.installer import BinaryInstaller, call_system_requirements from conans.client.loader import load_python_file from conans.errors import ConanException, ConanInvalidConfiguration -from conans.util.files import rmdir +from conans.util.files import rmdir, mkdir class InstallAPI: @@ -46,8 +46,10 @@ def install_consumer(self, deps_graph, generators=None, source_folder=None, outp conanfile.folders.set_base_folders(source_folder, output_folder) # The previous .set_base_folders has already decided between the source_folder and output - base_folder = conanfile.folders.base_build - _do_deploys(self.conan_api, deps_graph, deploy, base_folder) + if deploy: + base_folder = conanfile.folders.base_build + mkdir(base_folder) + _do_deploys(self.conan_api, deps_graph, deploy, base_folder) conanfile.generators = list(set(conanfile.generators).union(generators or [])) app = ConanApp(self.conan_api.cache_folder) diff --git a/conans/test/functional/command/test_install_deploy.py b/conans/test/functional/command/test_install_deploy.py index 33a6263b153..d004cc0f5de 100644 --- a/conans/test/functional/command/test_install_deploy.py +++ b/conans/test/functional/command/test_install_deploy.py @@ -6,6 +6,7 @@ from conans.test.assets.cmake import gen_cmakelists from conans.test.assets.genconanfile import GenConanfile from conans.test.assets.sources import gen_function_cpp +from conans.test.utils.test_files import temp_folder from conans.test.utils.tools import TestClient from conans.util.files import save @@ -45,6 +46,25 @@ def deploy(conanfile, output_folder, **kwargs): c.run_command("cmake --build . --config Release") +def test_copy_files_deploy(): + c = TestClient() + deploy = textwrap.dedent(""" + import os, shutil + + def deploy(conanfile, output_folder, **kwargs): + for r, d in conanfile.dependencies.items(): + bindir = os.path.join(d.package_folder, "bin") + for f in os.listdir(bindir): + shutil.copy2(os.path.join(bindir, f), os.path.join(output_folder, f)) + """) + c.save({"conanfile.txt": "[requires]\nhello/0.1", + "deploy.py": deploy, + "hello/conanfile.py": GenConanfile("hello", "0.1").with_package_file("bin/file.txt", + "content!!")}) + c.run("create hello") + c.run("install . --deploy=deploy.py -of=mydeploy") + + def test_multi_deploy(): """ check that we can add more than 1 deployer in the command line, both in local folders and in cache. @@ -168,9 +188,11 @@ def test_deploy_editable(): "src/include/hi.h": "hi"}) c.run("editable add . pkg/1.0") - c.run("install --requires=pkg/1.0 --deploy=full_deploy --output-folder=output") - header = c.load("output/host/pkg/1.0/src/include/hi.h") - assert "hi" in header + # If we don't change to another folder, the full_deploy will be recursive and fail + with c.chdir(temp_folder()): + c.run("install --requires=pkg/1.0 --deploy=full_deploy --output-folder=output") + header = c.load("output/host/pkg/1.0/src/include/hi.h") + assert "hi" in header def test_deploy_single_package(): From 295eabbb1c05abefa85d93bd570d101597c5c30c Mon Sep 17 00:00:00 2001 From: memsharded Date: Sat, 3 Sep 2022 12:45:43 +0200 Subject: [PATCH 2/3] fixing env_info for deployers --- conan/tools/env/environment.py | 15 +++++++++++++++ conans/model/conan_file.py | 2 ++ conans/model/dependencies.py | 19 ++++++++++++++++--- .../integration/package_id/build_id_test.py | 18 ++++++++++++++++++ 4 files changed, 51 insertions(+), 3 deletions(-) diff --git a/conan/tools/env/environment.py b/conan/tools/env/environment.py index 0f599db7198..371fbbd3aed 100644 --- a/conan/tools/env/environment.py +++ b/conan/tools/env/environment.py @@ -154,6 +154,16 @@ def get_value(self, subsystem, pathsep): previous_value = os.getenv(self._name) return self.get_str(previous_value, subsystem, pathsep) + def deploy_base_folder(self, package_folder, deploy_folder): + """Prepend the folder to all the directories""" + if not self._path: + return + for i, v in enumerate(self._values): + if v is _EnvVarPlaceHolder: + continue + rel_path = os.path.relpath(v, package_folder) + self._values[i] = os.path.join(deploy_folder, rel_path) + class Environment: """ @@ -286,6 +296,11 @@ def vars(self, conanfile, scope="build"): """ return EnvVars(conanfile, self, scope) + def deploy_base_folder(self, package_folder, deploy_folder): + """Prepend the folder to all the directories""" + for varvalues in self._values.values(): + varvalues.deploy_base_folder(package_folder, deploy_folder) + class EnvVars: """ diff --git a/conans/model/conan_file.py b/conans/model/conan_file.py index dd601992fd9..f8f64ddc7b2 100644 --- a/conans/model/conan_file.py +++ b/conans/model/conan_file.py @@ -420,4 +420,6 @@ def __repr__(self): def set_deploy_folder(self, deploy_folder): self.cpp_info.deploy_base_folder(self.package_folder, deploy_folder) + self.buildenv_info.deploy_base_folder(self.package_folder, deploy_folder) + self.runenv_info.deploy_base_folder(self.package_folder, deploy_folder) self.folders.set_base_package(deploy_folder) diff --git a/conans/model/dependencies.py b/conans/model/dependencies.py index 56db54aadb6..af6fef95a03 100644 --- a/conans/model/dependencies.py +++ b/conans/model/dependencies.py @@ -26,6 +26,10 @@ def __bool__(self): return bool(self._data) def get(self, ref, build=None, **kwargs): + r, v = self._get(ref, build, **kwargs) + return v + + def _get(self, ref, build=None, **kwargs): if build is None: current_filters = self._require_filter or {} if "build" not in current_filters: @@ -54,14 +58,23 @@ def get(self, ref, build=None, **kwargs): if not ret: raise KeyError("'{}' not found in the dependency set".format(ref)) - _, value = ret[0] - return value + require, value = ret[0] + return require, value def __getitem__(self, name): return self.get(name) def __delitem__(self, name): - r = self.get(name) + r, _ = self._get(name) + print("LEN", len(self._data)) + print("IN", r in self._data) + print("NOT IN", r not in self._data) + print("ID", id(r)) + d = list(self._data.keys())[0] + print("ID data", id(d)) + print("LETS DELETE FROM DICT") + print(type(r), r) + print(type(d), d) del self._data[r] def items(self): diff --git a/conans/test/integration/package_id/build_id_test.py b/conans/test/integration/package_id/build_id_test.py index 5a5b226192b..4540c734af1 100644 --- a/conans/test/integration/package_id/build_id_test.py +++ b/conans/test/integration/package_id/build_id_test.py @@ -7,6 +7,7 @@ from conans.model.package_ref import PkgReference from conans.model.recipe_ref import RecipeReference +from conans.test.assets.genconanfile import GenConanfile from conans.test.utils.tools import TestClient from conans.util.files import load @@ -275,3 +276,20 @@ def build(self): self.assertIn("ERROR: pkg/0.1@user/channel: Error in build() method, line 5", client.out) client.run("create . --name=pkg --version=0.1 --user=user --channel=channel", assert_error=True) self.assertIn("ERROR: pkg/0.1@user/channel: Error in build() method, line 5", client.out) + + +def test_remove_require(): + c = TestClient() + remove = textwrap.dedent(""" + from conan import ConanFile + class Pkg(ConanFile): + name = "consumer" + version = "1.0" + requires = "dep/1.0" + def build_id(self): + self.info_build.requires.remove("dep") + """) + c.save({"dep/conanfile.py": GenConanfile("dep", "1.0"), + "consumer/conanfile.py": remove}) + c.run("create dep") + c.run("create consumer") From 3ecb0616e27454b48499b461ea364d6735493fd6 Mon Sep 17 00:00:00 2001 From: memsharded Date: Sat, 3 Sep 2022 12:51:41 +0200 Subject: [PATCH 3/3] review --- conan/tools/env/environment.py | 4 ++-- conans/model/dependencies.py | 19 +++---------------- .../integration/package_id/build_id_test.py | 18 ------------------ 3 files changed, 5 insertions(+), 36 deletions(-) diff --git a/conan/tools/env/environment.py b/conan/tools/env/environment.py index 371fbbd3aed..cd47d52a563 100644 --- a/conan/tools/env/environment.py +++ b/conan/tools/env/environment.py @@ -155,7 +155,7 @@ def get_value(self, subsystem, pathsep): return self.get_str(previous_value, subsystem, pathsep) def deploy_base_folder(self, package_folder, deploy_folder): - """Prepend the folder to all the directories""" + """Make the path relative to the deploy_folder""" if not self._path: return for i, v in enumerate(self._values): @@ -297,7 +297,7 @@ def vars(self, conanfile, scope="build"): return EnvVars(conanfile, self, scope) def deploy_base_folder(self, package_folder, deploy_folder): - """Prepend the folder to all the directories""" + """Make the paths relative to the deploy_folder""" for varvalues in self._values.values(): varvalues.deploy_base_folder(package_folder, deploy_folder) diff --git a/conans/model/dependencies.py b/conans/model/dependencies.py index af6fef95a03..56db54aadb6 100644 --- a/conans/model/dependencies.py +++ b/conans/model/dependencies.py @@ -26,10 +26,6 @@ def __bool__(self): return bool(self._data) def get(self, ref, build=None, **kwargs): - r, v = self._get(ref, build, **kwargs) - return v - - def _get(self, ref, build=None, **kwargs): if build is None: current_filters = self._require_filter or {} if "build" not in current_filters: @@ -58,23 +54,14 @@ def _get(self, ref, build=None, **kwargs): if not ret: raise KeyError("'{}' not found in the dependency set".format(ref)) - require, value = ret[0] - return require, value + _, value = ret[0] + return value def __getitem__(self, name): return self.get(name) def __delitem__(self, name): - r, _ = self._get(name) - print("LEN", len(self._data)) - print("IN", r in self._data) - print("NOT IN", r not in self._data) - print("ID", id(r)) - d = list(self._data.keys())[0] - print("ID data", id(d)) - print("LETS DELETE FROM DICT") - print(type(r), r) - print(type(d), d) + r = self.get(name) del self._data[r] def items(self): diff --git a/conans/test/integration/package_id/build_id_test.py b/conans/test/integration/package_id/build_id_test.py index 4540c734af1..5a5b226192b 100644 --- a/conans/test/integration/package_id/build_id_test.py +++ b/conans/test/integration/package_id/build_id_test.py @@ -7,7 +7,6 @@ from conans.model.package_ref import PkgReference from conans.model.recipe_ref import RecipeReference -from conans.test.assets.genconanfile import GenConanfile from conans.test.utils.tools import TestClient from conans.util.files import load @@ -276,20 +275,3 @@ def build(self): self.assertIn("ERROR: pkg/0.1@user/channel: Error in build() method, line 5", client.out) client.run("create . --name=pkg --version=0.1 --user=user --channel=channel", assert_error=True) self.assertIn("ERROR: pkg/0.1@user/channel: Error in build() method, line 5", client.out) - - -def test_remove_require(): - c = TestClient() - remove = textwrap.dedent(""" - from conan import ConanFile - class Pkg(ConanFile): - name = "consumer" - version = "1.0" - requires = "dep/1.0" - def build_id(self): - self.info_build.requires.remove("dep") - """) - c.save({"dep/conanfile.py": GenConanfile("dep", "1.0"), - "consumer/conanfile.py": remove}) - c.run("create dep") - c.run("create consumer")