From 406d3f7779acd3d2b57e231827dc0834ceb21637 Mon Sep 17 00:00:00 2001 From: James Date: Tue, 19 May 2020 10:32:31 +0200 Subject: [PATCH] let deploy generator install symlinks (#7044) * let deploy generator install symlinks * fixing tests * more tests --- conans/client/generators/deploy.py | 7 ++- .../test/functional/generators/deploy_test.py | 57 ++++++++++++++++++- conans/test/utils/genconanfile.py | 11 +++- 3 files changed, 70 insertions(+), 5 deletions(-) diff --git a/conans/client/generators/deploy.py b/conans/client/generators/deploy.py index daf8f50d424..2d412db629a 100644 --- a/conans/client/generators/deploy.py +++ b/conans/client/generators/deploy.py @@ -43,7 +43,12 @@ def content(self): dst = os.path.normpath(dst) mkdir(os.path.dirname(dst)) if os.path.islink(src): - linkto = os.path.relpath(os.readlink(src), os.path.dirname(src)) + link_target = os.readlink(src) + if not os.path.isabs(link_target): + link_target = os.path.join(os.path.dirname(src), link_target) + linkto = os.path.relpath(link_target, os.path.dirname(src)) + if os.path.isfile(dst) or os.path.islink(dst): + os.unlink(dst) os.symlink(linkto, dst) else: shutil.copy(src, dst) diff --git a/conans/test/functional/generators/deploy_test.py b/conans/test/functional/generators/deploy_test.py index d8ff9f87fc8..9ae8ec2eda9 100644 --- a/conans/test/functional/generators/deploy_test.py +++ b/conans/test/functional/generators/deploy_test.py @@ -5,6 +5,7 @@ from conans import load from conans.model.ref import ConanFileReference, PackageReference +from conans.util.files import save from conans.test.utils.test_files import temp_folder from conans.test.utils.tools import GenConanfile, TurboTestClient, NO_SETTINGS_PACKAGE_ID @@ -145,7 +146,7 @@ class DeployGeneratorSymbolicLinkTest(unittest.TestCase): def setUp(self): conanfile = GenConanfile() - conanfile.with_package_file("include/header.h", "whatever") + conanfile.with_package_file("include/header.h", "whatever", link="include/header.h.lnk") self.ref = ConanFileReference("name", "version", "user", "channel") self.client = TurboTestClient() @@ -153,10 +154,9 @@ def setUp(self): layout = self.client.cache.package_layout(self.ref) package_folder = layout.package(PackageReference(self.ref, NO_SETTINGS_PACKAGE_ID)) self.header_path = os.path.join(package_folder, "include", "header.h") + self.link_path = os.path.join(package_folder, "include", "header.h.lnk") def test_symbolic_links(self): - link_path = self.header_path + ".lnk" - os.symlink(self.header_path, link_path) self.client.current_folder = temp_folder() self.client.run("install %s -g deploy" % self.ref.full_str()) base_path = os.path.join(self.client.current_folder, "name") @@ -166,3 +166,54 @@ def test_symbolic_links(self): self.assertFalse(os.path.islink(header_path)) linkto = os.path.join(os.path.dirname(link_path), os.readlink(link_path)) self.assertEqual(linkto, header_path) + + def test_existing_link_symbolic_links(self): + self.client.current_folder = temp_folder() + base_path = os.path.join(self.client.current_folder, "name") + header_path = os.path.join(base_path, "include", "header.h") + link_path = os.path.join(base_path, "include", "header.h.lnk") + save(link_path, "") + self.client.run("install %s -g deploy" % self.ref.full_str()) + self.assertTrue(os.path.islink(link_path)) + self.assertFalse(os.path.islink(header_path)) + linkto = os.path.join(os.path.dirname(link_path), os.readlink(link_path)) + self.assertEqual(linkto, header_path) + + def test_existing_real_link_symbolic_links(self): + self.client.current_folder = temp_folder() + base_path = os.path.join(self.client.current_folder, "name") + header_path = os.path.join(base_path, "include", "header.h") + link_path = os.path.join(base_path, "include", "header.h.lnk") + save(header_path, "") + os.symlink(header_path, link_path) + self.client.run("install %s -g deploy" % self.ref.full_str()) + self.assertTrue(os.path.islink(link_path)) + self.assertFalse(os.path.islink(header_path)) + linkto = os.path.join(os.path.dirname(link_path), os.readlink(link_path)) + self.assertEqual(linkto, header_path) + + def test_existing_broken_link_symbolic_links(self): + self.client.current_folder = temp_folder() + base_path = os.path.join(self.client.current_folder, "name") + header_path = os.path.join(base_path, "include", "header.h") + link_path = os.path.join(base_path, "include", "header.h.lnk") + save(header_path, "") + os.symlink(header_path, link_path) + os.remove(header_path) # This will make it a broken symlink + self.client.run("install %s -g deploy" % self.ref.full_str()) + self.assertTrue(os.path.islink(link_path)) + self.assertFalse(os.path.islink(header_path)) + linkto = os.path.join(os.path.dirname(link_path), os.readlink(link_path)) + self.assertEqual(linkto, header_path) + + def test_existing_file_symbolic_links(self): + self.client.current_folder = temp_folder() + base_path = os.path.join(self.client.current_folder, "name") + header_path = os.path.join(base_path, "include", "header.h") + link_path = os.path.join(base_path, "include", "header.h.lnk") + save(header_path, "") + self.client.run("install %s -g deploy" % self.ref.full_str()) + self.assertTrue(os.path.islink(link_path)) + self.assertFalse(os.path.islink(header_path)) + linkto = os.path.join(os.path.dirname(link_path), os.readlink(link_path)) + self.assertEqual(linkto, header_path) diff --git a/conans/test/utils/genconanfile.py b/conans/test/utils/genconanfile.py index 308982fb725..b7315fc3693 100644 --- a/conans/test/utils/genconanfile.py +++ b/conans/test/utils/genconanfile.py @@ -22,6 +22,7 @@ def __init__(self, name=None, version=None): self._default_options = {} self._package_files = {} self._package_files_env = {} + self._package_files_link = {} self._build_messages = [] self._scm = {} self._requires = [] @@ -90,13 +91,15 @@ def with_default_option(self, option_name, value): self._default_options[option_name] = value return self - def with_package_file(self, file_name, contents=None, env_var=None): + def with_package_file(self, file_name, contents=None, env_var=None, link=None): if not contents and not env_var: raise Exception("Specify contents or env_var") self.with_import("import os") self.with_import("from conans import tools") if contents: self._package_files[file_name] = contents + if link: + self._package_files_link[file_name] = link if env_var: self._package_files_env[file_name] = env_var return self @@ -229,6 +232,12 @@ def _package_method(self): lines.extend([' tools.save(os.path.join(self.package_folder, "{}"), ' 'os.getenv("{}"))'.format(key, value) for key, value in self._package_files_env.items()]) + if self._package_files_link: + lines.extend([' with tools.chdir(os.path.dirname(' + 'os.path.join(self.package_folder, "{}"))):\n' + ' os.symlink(os.path.basename("{}"), ' + 'os.path.join(self.package_folder, "{}"))'.format(key, key, value) + for key, value in self._package_files_link.items()]) if not lines: return ""