summaryrefslogtreecommitdiffstats
path: root/base/common/python
diff options
context:
space:
mode:
authorEndi S. Dewata <edewata@redhat.com>2016-12-20 17:59:18 +0100
committerEndi S. Dewata <edewata@redhat.com>2016-12-21 03:04:34 +0100
commit9822676b7f00cc7e78d42c50c2506a289ed9c1c6 (patch)
tree0334a13706461c47fb6c4f39c46810ede4fd29cf /base/common/python
parent843cbeed6ddab8f1883abce47a8c45e0fa14fc5a (diff)
downloadpki-9822676b7f00cc7e78d42c50c2506a289ed9c1c6.tar.gz
pki-9822676b7f00cc7e78d42c50c2506a289ed9c1c6.tar.xz
pki-9822676b7f00cc7e78d42c50c2506a289ed9c1c6.zip
Refactored pki_copytree().
The pki_copytree() has been moved from pkihelper.py into pki/util.py such that it can be reused in non-deployment scenarios.
Diffstat (limited to 'base/common/python')
-rw-r--r--base/common/python/pki/util.py76
1 files changed, 76 insertions, 0 deletions
diff --git a/base/common/python/pki/util.py b/base/common/python/pki/util.py
index 95a367055..8a75ff6f5 100644
--- a/base/common/python/pki/util.py
+++ b/base/common/python/pki/util.py
@@ -26,6 +26,11 @@ Module containing utility functions and classes for the Dogtag python code
from __future__ import absolute_import
import os
import shutil
+from shutil import Error
+try:
+ from shutil import WindowsError # pylint: disable=E0611
+except ImportError:
+ WindowsError = None
def copy(source, dest):
@@ -136,3 +141,74 @@ def customize_file(input_file, output_file, params):
for src, target in params.items():
line = line.replace(src, target)
outfile.write(line)
+
+
+def copytree(src, dst, symlinks=False, ignore=None):
+ """
+ Recursively copy a directory tree using copy2().
+
+ PATCH: This code was copied from 'shutil.py' and patched to
+ allow 'The destination directory to already exist.'
+
+ If exception(s) occur, an Error 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.
+
+ The optional ignore argument is a callable. If given, it
+ is called with the `src` parameter, which is the directory
+ being visited by copytree(), and `names` which is the list of
+ `src` contents, as returned by os.listdir():
+
+ callable(src, names) -> ignored_names
+
+ Since copytree() is called recursively, the callable will be
+ called once for each directory that is copied. It returns a
+ list of names relative to the `src` directory that should
+ not be copied.
+
+ Consider this example code rather than the ultimate tool.
+ """
+ names = os.listdir(src)
+ if ignore is not None:
+ ignored_names = ignore(src, names)
+ else:
+ ignored_names = set()
+
+ # PATCH: ONLY execute 'os.makedirs(dst)' if the top-level
+ # destination directory does NOT exist!
+ if not os.path.exists(dst):
+ os.makedirs(dst)
+ errors = []
+ for name in names:
+ if name in ignored_names:
+ continue
+ 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):
+ copytree(srcname, dstname, symlinks, ignore)
+ else:
+ # Will raise a SpecialFileError for unsupported file types
+ shutil.copy2(srcname, dstname)
+ # catch the Error from the recursive copytree so that we can
+ # continue with other files
+ except Error as err:
+ errors.extend(err.args[0])
+ except EnvironmentError as why:
+ errors.append((srcname, dstname, str(why)))
+ try:
+ shutil.copystat(src, dst)
+ except OSError as why:
+ if WindowsError is not None and isinstance(why, WindowsError):
+ # Copying file access times may fail on Windows
+ pass
+ else:
+ errors.extend((src, dst, str(why)))
+ if errors:
+ raise Error(errors)