Skip to content

Commit

Permalink
let deploy generator install symlinks (#7044)
Browse files Browse the repository at this point in the history
* let deploy generator install symlinks

* fixing tests

* more tests
  • Loading branch information
memsharded committed May 19, 2020
1 parent 31f9f90 commit 406d3f7
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 5 deletions.
7 changes: 6 additions & 1 deletion conans/client/generators/deploy.py
Expand Up @@ -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)
Expand Down
57 changes: 54 additions & 3 deletions conans/test/functional/generators/deploy_test.py
Expand Up @@ -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

Expand Down Expand Up @@ -145,18 +146,17 @@ 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()
self.client.create(self.ref, conanfile)
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")
Expand All @@ -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)
11 changes: 10 additions & 1 deletion conans/test/utils/genconanfile.py
Expand Up @@ -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 = []
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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 ""
Expand Down

0 comments on commit 406d3f7

Please sign in to comment.