Skip to content
Closed
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
116 changes: 42 additions & 74 deletions easybuild/tools/filetools.py
Original file line number Diff line number Diff line change
Expand Up @@ -717,6 +717,9 @@ 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'):
dry_run_msg("Adjusting permissions for %s to %s" % (name, permissionBits), silent=build_option('silent'))
return

name = os.path.abspath(name)

Expand Down Expand Up @@ -1003,80 +1006,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)
"""Has been replaced by copy_files"""
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

include DEPRECATED in the docstring please

_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):
Expand Down Expand Up @@ -1158,3 +1090,39 @@ def det_size(path):
_log.warn("Could not determine install size: %s" % err)

return installsize


def copy_files(src, dst, symlinks=False, ignore=None):
"""
Wrapper around shutil.copytree to nicely handle extended dry run
Arguments are the same as for the original function
The destination directoy must not exist
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo: directory

"""
if build_option('extended_dry_run'):
dry_run_msg("Copying directory %s to %s" % (src, dst), silent=build_option('silent'))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

copy_files should be able to copy both files and directories imho...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, it should. I will look if I find some time

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please make this (WIP) in the mean time

return

if os.path.exists(dst):
raise EasyBuildError("Destination directory %s of copy already exists.", dst)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is this needed?

do we know why copytree does this?

it would be useful if we're able to cope with this...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's in the docs that it must be so. We could integrate it here to delete the directory if it exists but I'm not sure if that is what we want

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see why we shouldn't, if the directory is empty, that is.
Otherwise the caller is simply going to do exactly that anyway?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

well, it the dir is empty, sure


try:
_log.debug("Copying directory %s to %s" % (src, dst))
shutil.copytree(src, dst, symlinks=symlinks, ignore=ignore)
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)