summaryrefslogtreecommitdiffstats
path: root/src/engine
diff options
context:
space:
mode:
authorGary Oberbrunner <garyo@oberbrunner.com>2010-11-18 13:48:37 (GMT)
committerGary Oberbrunner <garyo@oberbrunner.com>2010-11-18 13:48:37 (GMT)
commit3f478c8dbe11dbb4eabb77cf6443a10ed039af0d (patch)
tree16d9c6c9ebd7647d7cd8bb2b4e5567a68983fbe0 /src/engine
parent9de4764cf8bdfb9da9565e3c38878eb1c1b03377 (diff)
downloadSCons-3f478c8dbe11dbb4eabb77cf6443a10ed039af0d.zip
SCons-3f478c8dbe11dbb4eabb77cf6443a10ed039af0d.tar.gz
SCons-3f478c8dbe11dbb4eabb77cf6443a10ed039af0d.tar.bz2
Fix Install() when src and target are dirs and target dir already exists, by using our own copytree implementation.
Diffstat (limited to 'src/engine')
-rw-r--r--src/engine/SCons/Tool/install.py56
1 files changed, 55 insertions, 1 deletions
diff --git a/src/engine/SCons/Tool/install.py b/src/engine/SCons/Tool/install.py
index f328248..7e5fed5 100644
--- a/src/engine/SCons/Tool/install.py
+++ b/src/engine/SCons/Tool/install.py
@@ -44,6 +44,60 @@ from SCons.Util import make_path_relative
_INSTALLED_FILES = []
_UNIQUE_INSTALLED_FILES = None
+class CopytreeError(EnvironmentError):
+ pass
+
+# This is a patched version of shutil.copytree from python 2.5. It
+# doesn't fail if the dir exists, which regular copytree does
+# (annoyingly). Note the XXX comment in the docstring.
+def scons_copytree(src, dst, symlinks=False):
+ """Recursively copy a directory tree using copy2().
+
+ The destination directory must not already exist.
+ If exception(s) occur, an CopytreeError is raised with a list of reasons.
+
+ If the optional symlinks flag is true, symbolic links in the
+ source tree result in symbolic links in the destination tree; if
+ it is false, the contents of the files pointed to by symbolic
+ links are copied.
+
+ XXX Consider this example code rather than the ultimate tool.
+
+ """
+ names = os.listdir(src)
+ # garyo@genarts.com fix: check for dir before making dirs.
+ if not os.path.exists(dst):
+ os.makedirs(dst)
+ errors = []
+ for name in names:
+ srcname = os.path.join(src, name)
+ dstname = os.path.join(dst, name)
+ try:
+ if symlinks and os.path.islink(srcname):
+ linkto = os.readlink(srcname)
+ os.symlink(linkto, dstname)
+ elif os.path.isdir(srcname):
+ scons_copytree(srcname, dstname, symlinks)
+ else:
+ shutil.copy2(srcname, dstname)
+ # XXX What about devices, sockets etc.?
+ except (IOError, os.error), why:
+ errors.append((srcname, dstname, str(why)))
+ # catch the CopytreeError from the recursive copytree so that we can
+ # continue with other files
+ except CopytreeError, err:
+ errors.extend(err.args[0])
+ try:
+ shutil.copystat(src, dst)
+ except WindowsError:
+ # can't copy file access times on Windows
+ pass
+ except OSError, why:
+ errors.extend((src, dst, str(why)))
+ if errors:
+ raise CopytreeError, errors
+
+
#
# Functions doing the actual work of the Install Builder.
#
@@ -59,7 +113,7 @@ def copyFunc(dest, source, env):
parent = os.path.split(dest)[0]
if not os.path.exists(parent):
os.makedirs(parent)
- shutil.copytree(source, dest)
+ scons_copytree(source, dest)
else:
shutil.copy2(source, dest)
st = os.stat(source)