From 279073dbb3eb03fbe1f897bd142a53d7c4c5bc7d Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Mon, 22 Oct 2018 19:59:07 -0400
Subject: [PATCH] DRTVWR-447: Introduce LLManifest.process_either().

process_directory() and process_file() are reached both from the top-level
caller (try_path(), a local function within LLManifest.path()) and recursively
from process_directory(). Both places tested os.path.isdir(source), and if so
called process_directory(), else process_file(). Both places were wrong, as it
turns out.

os.path.isdir(symlink_to_directory) returns True. That meant that despite
explicit logic in ccopymumble() to recreate symlinks in the destination area,
we were consistently recopying the contents of symlinked directories.

The downside to this -- in addition to inflating the size of the installer! --
is that macOS is very particular about the structure of a Framework bundle. It
*must* include a Versions/Current symlink identifying which of the other
Versions subdirectories is, in fact, current. If Current is itself a
subdirectory, codesign can't figure out how to sign the framework, and fails.

The logic for deciding between process_directory() and process_file() must
explicitly check for os.path.islink(source). Rather than replicating that
change in both places, introduce process_either() which decides how to forward
the call, and call it both from try_path() and from process_directory().
---
 indra/lib/python/indra/util/llmanifest.py | 19 ++++++++++---------
 1 file changed, 10 insertions(+), 9 deletions(-)

diff --git a/indra/lib/python/indra/util/llmanifest.py b/indra/lib/python/indra/util/llmanifest.py
index 9569014a470..2e6cf53912c 100755
--- a/indra/lib/python/indra/util/llmanifest.py
+++ b/indra/lib/python/indra/util/llmanifest.py
@@ -615,6 +615,14 @@ def cleanup_finish(self):
             # *TODO is this gonna be useful?
             print "Cleaning up " + c
 
+    def process_either(self, src, dst):
+        # If it's a real directory, recurse through it --
+        # but not a symlink! Handle those like files.
+        if os.path.isdir(src) and not os.path.islink(src):
+            return self.process_directory(src, dst)
+        else:
+            return self.process_file(src, dst)
+
     def process_file(self, src, dst):
         if self.includes(src, dst):
             for action in self.actions:
@@ -641,10 +649,7 @@ def process_directory(self, src, dst):
         for name in names:
             srcname = os.path.join(src, name)
             dstname = os.path.join(dst, name)
-            if os.path.isdir(srcname):
-                count += self.process_directory(srcname, dstname)
-            else:
-                count += self.process_file(srcname, dstname)
+            count += self.process_either(srcname, dstname)
         return count
 
     def includes(self, src, dst):
@@ -816,11 +821,7 @@ def try_path(src):
                 # if we're specifying a single path (not a glob),
                 # we should error out if it doesn't exist
                 self.check_file_exists(src)
-                # if it's a directory, recurse through it
-                if os.path.isdir(src):
-                    count += self.process_directory(src, dst)
-                else:
-                    count += self.process_file(src, dst)
+                count += self.process_either(src, dst)
             return count
 
         try_prefixes = [self.get_src_prefix(), self.get_artwork_prefix(), self.get_build_prefix()]
-- 
GitLab