Repository: conan-io/conan

Issue:
[bug] Deploy generator does not copy symbolic links to directories
<!--
  Please don't forget to update the issue title.
  Include all applicable information to help us reproduce your problem.

  To help us debug your issue please explain:
-->
Symbolic links to directories are not copied by the `deploy` command.
For example, the following structure will be mising `root/current/`:
```
root/
 | 1.0/
 - | file.txt
 | 1.2/
 - | file.txt
 | current/ -> 1.0/
 | file.txt -> current/file.txt
```
Since `root/current/` is not copied, it will break the other symbolic links such as `root/file.txt`.

Similar issue to #6628 but for symbolic links to directories instead of files.

A simple solution would be to just add symbolic links to directories to the files copied, but you cannot add them to the copied files list. So essentially something like this:
```diff
...
            rootpath = self.conanfile.deps_cpp_info[dep_name].rootpath
-            for root, _, files in os.walk(os.path.normpath(rootpath)):
+            for root, dirs, files in os.walk(os.path.normpath(rootpath)):
+               files += [d for d in dirs if os.path.islink(os.path.join(root, d))]
                for f in files:

...

                        shutil.copy(src, dst)
-                    copied_files.append(dst)
+                    if f not in dirs:
+                       copied_files.append(dst)
        return self.deploy_manifest_content(copied_files)
```
I have not tested this extensively so I will not open a pull request. It might also be a good idea to add this case to the `DeployGeneratorSymbolicLinkTest`.

### Environment Details
  * Operating System+version: Ubuntu 20.04 / 18.04
  * Conan version: 1.30.0-dev
  * Python version: 3.8.2

### Steps to reproduce

Deploy for example `icu`:
`conan install icu/64.2@bincrafters/stable -g deploy`


### Logs (Executed commands with output)

```
...
ERROR: Generator deploy(file:deploy_manifest.txt) failed
[Errno 2] No such file or directory: 'somewhere/icu/lib/icu/pkgdata.inc'
ERROR: [Errno 2] No such file or directory: 'somwhere/icu/lib/icu/pkgdata.inc'
```



Discussion:
Hi, thanks for the detailed report and the proposal.

I see this could be an easy fix so if you are willing to contribute the changes we can help you with the tests  😄 

Resolving patch:
diff --git a/conans/client/generators/deploy.py b/conans/client/generators/deploy.py
--- a/conans/client/generators/deploy.py
+++ b/conans/client/generators/deploy.py
@@ -33,7 +33,8 @@ def content(self):
 
         for dep_name in self.conanfile.deps_cpp_info.deps:
             rootpath = self.conanfile.deps_cpp_info[dep_name].rootpath
-            for root, _, files in os.walk(os.path.normpath(rootpath)):
+            for root, dirs, files in os.walk(os.path.normpath(rootpath)):
+                files += [d for d in dirs if os.path.islink(os.path.join(root, d))]
                 for f in files:
                     if f in FILTERED_FILES:
                         continue
@@ -52,5 +53,6 @@ def content(self):
                         os.symlink(linkto, dst)
                     else:
                         shutil.copy(src, dst)
-                    copied_files.append(dst)
+                    if f not in dirs:
+                        copied_files.append(dst)
         return self.deploy_manifest_content(copied_files)


Test patch:
diff --git a/conans/test/functional/generators/deploy_test.py b/conans/test/functional/generators/deploy_test.py
--- a/conans/test/functional/generators/deploy_test.py
+++ b/conans/test/functional/generators/deploy_test.py
@@ -1,6 +1,7 @@
 import os
 import platform
 import stat
+import textwrap
 import unittest
 
 from conans import load
@@ -217,3 +218,37 @@ def test_existing_file_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)
+
+
+@unittest.skipIf(platform.system() == "Windows", "Symlinks in NIX systems only")
+class DeployGeneratorSymbolicLinkFolderTest(unittest.TestCase):
+
+    def setUp(self):
+        conanfile = textwrap.dedent("""
+            import os
+            from conans import ConanFile, tools
+
+            class TestConan(ConanFile):
+
+                def package(self):
+                    folder_path = os.path.join(self.package_folder, "one_folder")
+                    tools.mkdir(folder_path)
+                    link_folder_path = os.path.join(self.package_folder, "other_folder")
+                    with tools.chdir(os.path.dirname(folder_path)):
+                        os.symlink(os.path.basename(folder_path), link_folder_path)
+        """)
+        self.ref = ConanFileReference("name", "version", "user", "channel")
+        self.client = TurboTestClient()
+        self.client.create(self.ref, conanfile)
+
+    def test_symbolic_links(self):
+        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")
+        folder_path = os.path.join(base_path, "one_folder")
+        link_folder_path = os.path.join(base_path, "other_folder")
+        self.assertTrue(os.path.islink(link_folder_path))
+        self.assertFalse(os.path.islink(folder_path))
+        linkto_folder = os.path.join(os.path.dirname(link_folder_path),
+                                     os.readlink(link_folder_path))
+        self.assertEqual(linkto_folder, folder_path)