diff --git a/easybuild/tools/filetools.py b/easybuild/tools/filetools.py index 7381bb1d92..8d50f19d44 100644 --- a/easybuild/tools/filetools.py +++ b/easybuild/tools/filetools.py @@ -1286,7 +1286,9 @@ def dir_contains_files(path, recursive=True): :recursive If False only the path itself is considered, else all subdirectories are also searched """ if recursive: - return any(files for _root, _dirs, files in os.walk(path)) + return any(os.path.isfile(os.path.join(root, file)) + for root, _dirs, files in os.walk(path, followlinks=True) + for file in files) else: return any(os.path.isfile(os.path.join(path, x)) for x in os.listdir(path)) diff --git a/test/framework/filetools.py b/test/framework/filetools.py index e7ce260afc..36d530d3da 100644 --- a/test/framework/filetools.py +++ b/test/framework/filetools.py @@ -2983,6 +2983,42 @@ def makedirs_in_test(*paths): self.assertTrue(ft.dir_contains_files(dir_w_dir_and_file)) self.assertTrue(ft.dir_contains_files(dir_w_dir_and_file, recursive=False)) + # Folder that is a symlink or contains a symlink to a folder + symlink_dir = makedirs_in_test('symlink_dir') + symlink_empty_folder = os.path.join(symlink_dir, 'to_empty') + ft.symlink(empty_dir, symlink_empty_folder) + self.assertFalse(ft.dir_contains_files(symlink_dir)) + self.assertFalse(ft.dir_contains_files(symlink_dir, recursive=False)) + self.assertFalse(ft.dir_contains_files(symlink_empty_folder)) + self.assertFalse(ft.dir_contains_files(symlink_empty_folder, recursive=False)) + symlink_full_folder = os.path.join(symlink_dir, 'to_full') + ft.symlink(dir_w_file, symlink_full_folder) + self.assertTrue(ft.dir_contains_files(symlink_dir)) + self.assertFalse(ft.dir_contains_files(symlink_dir, recursive=False)) + self.assertTrue(ft.dir_contains_files(symlink_full_folder)) + self.assertTrue(ft.dir_contains_files(symlink_full_folder, recursive=False)) + + dir_w_symlinked_file = makedirs_in_test('dir_w_symlinked_file') + ft.symlink(os.path.join(dir_w_file, 'file.h'), os.path.join(dir_w_symlinked_file, 'file.h')) + self.assertTrue(ft.dir_contains_files(dir_w_symlinked_file)) + self.assertTrue(ft.dir_contains_files(dir_w_symlinked_file, recursive=False)) + + dir_w_symlinked_file_in_subdir = makedirs_in_test('dir_w_symlinked_file_in_subdir', 'subdir') + subdir = os.path.join(dir_w_symlinked_file_in_subdir, 'subdir') + ft.symlink(os.path.join(dir_w_file, 'file.h'), + os.path.join(subdir, 'file.h')) + self.assertTrue(ft.dir_contains_files(dir_w_symlinked_file_in_subdir)) + self.assertFalse(ft.dir_contains_files(dir_w_symlinked_file_in_subdir, recursive=False)) + self.assertTrue(ft.dir_contains_files(subdir)) + self.assertTrue(ft.dir_contains_files(subdir, recursive=False)) + + # Broken symlink is not considered a file + ft.remove_file(os.path.join(dir_w_file, 'file.h')) + self.assertFalse(ft.dir_contains_files(dir_w_symlinked_file_in_subdir)) + self.assertFalse(ft.dir_contains_files(dir_w_symlinked_file_in_subdir, recursive=False)) + self.assertFalse(ft.dir_contains_files(subdir)) + self.assertFalse(ft.dir_contains_files(subdir, recursive=False)) + def test_find_eb_script(self): """Test find_eb_script function."""