diff --git a/easybuild/tools/filetools.py b/easybuild/tools/filetools.py index 9fc67412b8..63c6521c79 100644 --- a/easybuild/tools/filetools.py +++ b/easybuild/tools/filetools.py @@ -717,6 +717,21 @@ def adjust_permissions(name, permissionBits, add=True, onlyfiles=False, onlydirs Add or remove (if add is False) permissionBits from all files (if onlydirs is False) and directories (if onlyfiles is False) in path """ + if build_option('extended_dry_run'): + msg = '' + if recursive: + msg += 'Recursively ' + msg += 'adjusting permissions of %s ' % name + if add: + msg += ' by adding the following bits: %s ' % bin(permissionBits) + else: + msg += ' by removing the following bits: %s ' % bin(permissionBits) + + if group_id is not None: + msg += ' and group id to %s' % group_id + + dry_run_msg(msg, silent=build_option('silent')) + return name = os.path.abspath(name) @@ -1003,80 +1018,9 @@ def cleanup(logfile, tempdir, testing, silent=False): def copytree(src, dst, symlinks=False, ignore=None): - """ - Copied from Lib/shutil.py in python 2.7, since we need this to work for python2.4 aswell - and this code can be improved... - - Recursively copy a directory tree using copy2(). - - The destination directory must not 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. - - XXX Consider this example code rather than the ultimate tool. - - """ - class Error(EnvironmentError): - pass - try: - WindowsError # @UndefinedVariable - except NameError: - WindowsError = None - - names = os.listdir(src) - if ignore is not None: - ignored_names = ignore(src, names) - else: - ignored_names = set() - _log.debug("copytree: skipping copy of %s" % ignored_names) - 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, err: - errors.extend(err.args[0]) - except EnvironmentError, why: - errors.append((srcname, dstname, str(why))) - try: - shutil.copystat(src, dst) - except OSError, 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) + """Deprecated: has been replaced by copy_files""" + _log.deprecated("easybuild.tools.filetools.copytree has been replaced by copy_files", '3.0') + copy_files(src, dst, symlinks=symlinks, ignore=ignore) def encode_string(name): @@ -1158,3 +1102,61 @@ def det_size(path): _log.warn("Could not determine install size: %s" % err) return installsize + + +def copy_files(src, dst, symlinks=False, ignore=None): + """ + Copy the list of files or directories to a destintation + @src list or string of files and directories to copy + @dst the destination directory + @symlinks copy symlinks as symlinks + @ignore files to ignore in case the src is a directory + """ + if build_option('extended_dry_run'): + dry_run_msg("Copying directory %s to %s" % (src, dst), silent=build_option('silent')) + return + + if os.path.exists(dst): + if not os.path.isdir(dst): + raise EasyBuildError("File with the same name as destination directory %s \ + already exists.", dst) + elif not os.path.listdir(dst): + raise EasyBuildError("Destination directory %s of copy already exists.", dst) + else: + try: + _log.debug("Removing empty directory %s." % dst) + os.rmdir(dst) + except OSError, err: + raise EasyBuildError("Failed to remove %s: %s", dst, err) + + if isinstance(src, basestring): + src = [src] + + try: + for item in src: + if os.path.isfile(item): + _log.debug("Copying file %s to %s" % (item, dst)) + shutil.copy2(item, dst) + elif os.path.isdir(item): + _log.debug("Copying directory %s to %s" % (src, dst)) + shutil.copytree(item, dst, symlinks=symlinks, ignore=ignore) + else: + raise EasyBuildError("Can't copy non-existing path %s to %s", item, dst) + except OSError, err: + raise EasyBuildError("Failed to copy %s to %s: %s", src, dst, err) + + +def change_to(dst): + """ + Wrapper for os.chdir: change the directory to dst + @dst the destination directory + """ + if build_option('extended_dry_run'): + dry_run_msg("Changing directory to %s" % dst, silent=build_option('silent')) + return + + try: + _log.debug("Changing to directory %s" % dst) + os.chdir(dst) + except OSError, err: + raise EasyBuildError("Failed to move to directory %s: %s", dst, err)