summaryrefslogtreecommitdiffstats
path: root/meta/lib/oe/path.py
diff options
context:
space:
mode:
authorRichard Purdie <richard.purdie@linuxfoundation.org>2011-02-09 13:01:23 +0000
committerRichard Purdie <rpurdie@linux.intel.com>2011-02-09 22:46:30 +0000
commit58ae42cbc386a8cd59f12527d3e47bea82d9b36f (patch)
tree7df0d8bf79ebe53ab7a8bce8a0596272d9264f41 /meta/lib/oe/path.py
parentbb3db5106d4722ac177fcd5b2ae3d4e45d12be47 (diff)
downloadopenembedded-core-contrib-58ae42cbc386a8cd59f12527d3e47bea82d9b36f.tar.gz
lib.oe.path: Update copytree function to call shell commands since its twice as fast
As an added bonus, hardlinks between files in the tree will be preserved too. Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta/lib/oe/path.py')
-rw-r--r--meta/lib/oe/path.py44
1 files changed, 12 insertions, 32 deletions
diff --git a/meta/lib/oe/path.py b/meta/lib/oe/path.py
index f42faeab260..da7811fac47 100644
--- a/meta/lib/oe/path.py
+++ b/meta/lib/oe/path.py
@@ -46,43 +46,23 @@ def format_display(path, metadata):
return rel
-class Error(EnvironmentError):
+class CopyFailed(Exception):
pass
-# Based on shutil.copytree but with features removed and
-# No fatal error is dst already exists
-# Handle symlinks that already exist
def copytree(src, dst):
- names = os.listdir(src)
+ # We could use something like shutil.copytree here but it turns out to
+ # to be slow. It takes twice as long copying to an empty directory.
+ # If dst already has contents performance can be 15 time slower
+ # This way we also preserve hardlinks between files in the tree.
- bb.mkdirhier(dst)
+ import subprocess
- errors = []
- for name in names:
- srcname = os.path.join(src, name)
- dstname = os.path.join(dst, name)
- try:
- if os.path.islink(srcname):
- linkto = os.readlink(srcname)
- if os.path.lexists(dstname):
- os.unlink(dstname)
- os.symlink(linkto, dstname)
- elif os.path.isdir(srcname):
- copytree(srcname, dstname)
- else:
- bb.utils.copyfile(srcname, dstname)
- except (IOError, os.error), why:
- errors.append((srcname, dstname, str(why)))
- # catch the Error from the recursive copytree so that we can
- # continue with other files
- except Error, err:
- errors.extend(err.args[0])
- try:
- shutil.copystat(src, dst)
- except OSError, why:
- errors.extend((src, dst, str(why)))
- if errors:
- raise Error, errors
+ bb.mkdirhier(dst)
+ cmd = 'tar -cf - -C %s -ps . | tar -xf - -C %s' % (src, dst)
+ ret = subprocess.call(cmd, shell=True)
+ if ret != 0:
+ raise CopyFailed("Command %s failed with return value %s" % (cmd, ret))
+ return
def remove(path):
"""Equivalent to rm -f or rm -rf"""