Skip to content

Commit 114625c

Browse files
authored
Merge pull request #3152 from Flamefire/empty_folders
Only remove folders that contain no files recursively
2 parents 4f59a29 + b18e89b commit 114625c

File tree

3 files changed

+39
-11
lines changed

3 files changed

+39
-11
lines changed

easybuild/framework/easyblock.py

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@
7575
from easybuild.tools.filetools import diff_files, download_file, encode_class_name, extract_file
7676
from easybuild.tools.filetools import find_backup_name_candidate, get_source_tarball_from_git, is_alt_pypi_url
7777
from easybuild.tools.filetools import is_sha256_checksum, mkdir, move_file, move_logs, read_file, remove_dir
78-
from easybuild.tools.filetools import remove_file, rmtree2, verify_checksum, weld_paths, write_file
78+
from easybuild.tools.filetools import remove_file, rmtree2, verify_checksum, weld_paths, write_file, dir_contains_files
7979
from easybuild.tools.hooks import BUILD_STEP, CLEANUP_STEP, CONFIGURE_STEP, EXTENSIONS_STEP, FETCH_STEP, INSTALL_STEP
8080
from easybuild.tools.hooks import MODULE_STEP, PACKAGE_STEP, PATCH_STEP, PERMISSIONS_STEP, POSTITER_STEP, POSTPROC_STEP
8181
from easybuild.tools.hooks import PREPARE_STEP, READY_STEP, SANITYCHECK_STEP, SOURCE_STEP, TEST_STEP, TESTCASES_STEP
@@ -1305,15 +1305,14 @@ def make_module_req(self):
13051305
if path and not self.dry_run:
13061306
paths = sorted(glob.glob(path))
13071307
if paths and key in keys_requiring_files:
1308-
self.log.info("Only retaining paths for %s that include at least one file: %s", key, paths)
1309-
# only retain paths that include at least one file
1310-
retained_paths = []
1311-
for path in paths:
1312-
full_path = os.path.join(self.installdir, path)
1313-
if os.path.isdir(full_path):
1314-
if any(os.path.isfile(os.path.join(full_path, x)) for x in os.listdir(full_path)):
1315-
retained_paths.append(path)
1316-
self.log.info("Retained paths for %s: %s", key, retained_paths)
1308+
# only retain paths that contain at least one file
1309+
retained_paths = [
1310+
path for path in paths
1311+
if os.path.isdir(os.path.join(self.installdir, path))
1312+
and dir_contains_files(os.path.join(self.installdir, path))
1313+
]
1314+
self.log.info("Only retaining paths for %s that contain at least one file: %s -> %s",
1315+
key, paths, retained_paths)
13171316
paths = retained_paths
13181317
else:
13191318
# empty string is a valid value here (i.e. to prepend the installation prefix, cfr $CUDA_HOME)

easybuild/tools/filetools.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -681,6 +681,11 @@ def search_file(paths, query, short=False, ignore_dirs=None, silent=False, filen
681681
return var_defs, hits
682682

683683

684+
def dir_contains_files(path):
685+
"""Return True if the given directory does contain any file in itself or any subdirectory"""
686+
return any(files for _root, _dirs, files in os.walk(path))
687+
688+
684689
def find_eb_script(script_name):
685690
"""Find EasyBuild script with given name (in easybuild/scripts subdirectory)."""
686691
filetools, eb_dir = __file__, None
@@ -746,7 +751,7 @@ def calc_block_checksum(path, algorithm):
746751
try:
747752
# in hashlib, blocksize is a class parameter
748753
blocksize = algorithm.blocksize * 262144 # 2^18
749-
except AttributeError as err:
754+
except AttributeError:
750755
blocksize = 16777216 # 2^24
751756
_log.debug("Using blocksize %s for calculating the checksum" % blocksize)
752757

test/framework/filetools.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1724,6 +1724,30 @@ def test_search_file(self):
17241724
for pattern in ['*foo', '(foo', ')foo', 'foo)', 'foo(']:
17251725
self.assertErrorRegex(EasyBuildError, "Invalid search query", ft.search_file, [test_ecs], pattern)
17261726

1727+
def test_dir_contains_files(self):
1728+
def makedirs_in_test(*paths):
1729+
"""Make dir specified by paths and return top-level folder"""
1730+
os.makedirs(os.path.join(self.test_prefix, *paths))
1731+
return os.path.join(self.test_prefix, paths[0])
1732+
1733+
empty_dir = makedirs_in_test('empty_dir')
1734+
self.assertFalse(ft.dir_contains_files(empty_dir))
1735+
1736+
dir_w_subdir = makedirs_in_test('dir_w_subdir', 'sub_dir')
1737+
self.assertFalse(ft.dir_contains_files(dir_w_subdir))
1738+
1739+
dir_subdir_file = makedirs_in_test('dir_subdir_file', 'sub_dir_w_file')
1740+
ft.write_file(os.path.join(dir_subdir_file, 'sub_dir_w_file', 'file.h'), '')
1741+
self.assertTrue(ft.dir_contains_files(dir_subdir_file))
1742+
1743+
dir_w_file = makedirs_in_test('dir_w_file')
1744+
ft.write_file(os.path.join(dir_w_file, 'file.h'), '')
1745+
self.assertTrue(ft.dir_contains_files(dir_w_file))
1746+
1747+
dir_w_dir_and_file = makedirs_in_test('dir_w_dir_and_file', 'sub_dir')
1748+
ft.write_file(os.path.join(dir_w_dir_and_file, 'file.h'), '')
1749+
self.assertTrue(ft.dir_contains_files(dir_w_dir_and_file))
1750+
17271751
def test_find_eb_script(self):
17281752
"""Test find_eb_script function."""
17291753
self.assertTrue(os.path.exists(ft.find_eb_script('rpath_args.py')))

0 commit comments

Comments
 (0)