Skip to content
Closed
Changes from all 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
150 changes: 76 additions & 74 deletions easybuild/tools/filetools.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down Expand Up @@ -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):
Expand Down Expand Up @@ -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'))
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):
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)
Copy link
Member

Choose a reason for hiding this comment

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

you should take into account that individual files can also be symlinks, since copy2 resolves the symlink rather than copying it

cfr. http://stackoverflow.com/questions/4847615/copying-a-symbolic-link-in-python

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)