Skip to content
Merged
Show file tree
Hide file tree
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
8 changes: 6 additions & 2 deletions easybuild/tools/filetools.py
Original file line number Diff line number Diff line change
Expand Up @@ -2419,12 +2419,16 @@ def copy_file(path, target_path, force_in_dry_run=False):
try:
# check whether path to copy exists (we could be copying a broken symlink, which is supported)
path_exists = os.path.exists(path)
# If target is a folder, the target_path will be a file with the same name inside the folder
if os.path.isdir(target_path):
target_path = os.path.join(target_path, os.path.basename(path))
target_exists = os.path.exists(target_path)

if target_exists and path_exists and os.path.samefile(path, target_path):
_log.debug("Not copying %s to %s since files are identical", path, target_path)
# if target file exists and is owned by someone else than the current user,
# try using shutil.copyfile to just copy the file contents
# since shutil.copy2 will fail when trying to copy over file metadata (since chown requires file ownership)
# copy just the file contents (shutil.copyfile instead of shutil.copy2)
# since copying the file metadata/permissions will fail since chown requires file ownership
elif target_exists and os.stat(target_path).st_uid != os.getuid():
shutil.copyfile(path, target_path)
_log.info("Copied contents of file %s to %s", path, target_path)
Expand Down
13 changes: 13 additions & 0 deletions test/framework/filetools.py
Original file line number Diff line number Diff line change
Expand Up @@ -1856,6 +1856,19 @@ def test_copy_file(self):
# printing this message will make test suite fail in Travis/GitHub CI,
# since we check for unexpected output produced by the tests
print("Skipping overwrite-file-owned-by-other-user copy_file test (%s is missing)" % test_file_to_overwrite)
# Copy a file to a directory owned by some other user, e.g. /tmp (owned by root)
# This might be a common choice for e.g. --copy-ec
target_file_path = tempfile.mktemp("easybuild", dir="/tmp")
test_file_to_copy = os.path.join(self.test_prefix, os.path.basename(target_file_path))
ft.write_file(test_file_to_copy, test_file_contents)
try:
ft.copy_file(test_file_to_copy, '/tmp')
self.assertEqual(ft.read_file(target_file_path), test_file_contents)
finally:
try:
os.remove(target_file_path)
except FileNotFoundError:
pass

# also test behaviour of copy_file under --dry-run
build_options = {
Expand Down