Skip to content

Commit ca7fc1e

Browse files
authored
Merge pull request #2155 from boegel/chdir
implement change_dir function in filetools module
2 parents f23a568 + 15ec862 commit ca7fc1e

File tree

5 files changed

+69
-48
lines changed

5 files changed

+69
-48
lines changed

easybuild/framework/easyblock.py

Lines changed: 14 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@
6565
from easybuild.tools.config import install_path, log_path, package_path, source_paths
6666
from easybuild.tools.environment import restore_env, sanitize_env
6767
from easybuild.tools.filetools import DEFAULT_CHECKSUM
68-
from easybuild.tools.filetools import adjust_permissions, apply_patch, convert_name, derive_alt_pypi_url
68+
from easybuild.tools.filetools import adjust_permissions, apply_patch, change_dir, convert_name, derive_alt_pypi_url
6969
from easybuild.tools.filetools import compute_checksum, download_file, encode_class_name, extract_file
7070
from easybuild.tools.filetools import is_alt_pypi_url, mkdir, move_logs, read_file, remove_file, rmtree2, write_file
7171
from easybuild.tools.filetools import verify_checksum, weld_paths
@@ -1130,10 +1130,7 @@ def make_module_req(self):
11301130

11311131
lines = []
11321132
if os.path.isdir(self.installdir):
1133-
try:
1134-
os.chdir(self.installdir)
1135-
except OSError, err:
1136-
raise EasyBuildError("Failed to change to %s: %s", self.installdir, err)
1133+
change_dir(self.installdir)
11371134

11381135
lines.append('\n')
11391136

@@ -1162,10 +1159,7 @@ def make_module_req(self):
11621159
lines.append(self.module_generator.prepend_paths(key, paths))
11631160
if self.dry_run:
11641161
self.dry_run_msg('')
1165-
try:
1166-
os.chdir(self.orig_workdir)
1167-
except OSError, err:
1168-
raise EasyBuildError("Failed to change back to %s: %s", self.orig_workdir, err)
1162+
change_dir(self.orig_workdir)
11691163

11701164
return ''.join(lines)
11711165

@@ -1351,11 +1345,8 @@ def guess_start_dir(self):
13511345

13521346
self.log.info("Using %s as start dir", self.cfg['start_dir'])
13531347

1354-
try:
1355-
os.chdir(self.cfg['start_dir'])
1356-
self.log.debug("Changed to real build directory %s (start_dir)" % self.cfg['start_dir'])
1357-
except OSError, err:
1358-
raise EasyBuildError("Can't change to real build directory %s: %s", self.cfg['start_dir'], err)
1348+
change_dir(self.cfg['start_dir'])
1349+
self.log.debug("Changed to real build directory %s (start_dir)", self.cfg['start_dir'])
13591350

13601351
def handle_iterate_opts(self):
13611352
"""Handle options relevant during iterated part of build/install procedure."""
@@ -1726,7 +1717,7 @@ def extensions_step(self, fetch=False):
17261717
print_msg("installing extension %s %s (%d/%d)..." % tup, silent=self.silent)
17271718

17281719
# always go back to original work dir to avoid running stuff from a dir that no longer exists
1729-
os.chdir(self.orig_workdir)
1720+
change_dir(self.orig_workdir)
17301721

17311722
cls, inst = None, None
17321723
class_name = encode_class_name(ext['name'])
@@ -2052,10 +2043,7 @@ def _sanity_check_step(self, custom_paths=None, custom_commands=None, extension=
20522043

20532044
# chdir to installdir (better environment for running tests)
20542045
if os.path.isdir(self.installdir):
2055-
try:
2056-
os.chdir(self.installdir)
2057-
except OSError, err:
2058-
raise EasyBuildError("Failed to move to installdir %s: %s", self.installdir, err)
2046+
change_dir(self.installdir)
20592047

20602048
# run sanity check commands
20612049
for command in commands:
@@ -2101,11 +2089,12 @@ def cleanup_step(self):
21012089
cleanup_builddir is False, otherwise we remove the installation
21022090
"""
21032091
if not self.build_in_installdir and build_option('cleanup_builddir'):
2104-
try:
2105-
os.chdir(self.orig_workdir) # make sure we're out of the dir we're removing
21062092

2107-
self.log.info("Cleaning up builddir %s (in %s)" % (self.builddir, os.getcwd()))
2093+
# make sure we're out of the dir we're removing
2094+
change_dir(self.orig_workdir)
2095+
self.log.info("Cleaning up builddir %s (in %s)", self.builddir, os.getcwd())
21082096

2097+
try:
21092098
rmtree2(self.builddir)
21102099
base = os.path.dirname(self.builddir)
21112100

@@ -2237,7 +2226,7 @@ def test_cases_step(self):
22372226
Run provided test cases.
22382227
"""
22392228
for test in self.cfg['tests']:
2240-
os.chdir(self.orig_workdir)
2229+
change_dir(self.orig_workdir)
22412230
if os.path.isabs(test):
22422231
path = test
22432232
else:
@@ -2533,7 +2522,7 @@ def build_and_install_one(ecdict, init_env):
25332522
ended = 'ended'
25342523

25352524
# make sure we're back in original directory before we finish up
2536-
os.chdir(cwd)
2525+
change_dir(cwd)
25372526

25382527
application_log = None
25392528

@@ -2728,7 +2717,7 @@ def perform_step(step, obj, method, logfile):
27282717
start_time = time.time()
27292718

27302719
# start with a clean slate
2731-
os.chdir(base_dir)
2720+
change_dir(base_dir)
27322721
restore_env(base_env)
27332722
sanitize_env()
27342723

easybuild/framework/extension.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838

3939
from easybuild.tools.build_log import EasyBuildError
4040
from easybuild.tools.config import build_option, build_path
41+
from easybuild.tools.filetools import change_dir
4142
from easybuild.tools.run import run_cmd
4243

4344

@@ -113,10 +114,7 @@ def sanity_check_step(self):
113114
Sanity check to run after installing extension
114115
"""
115116

116-
try:
117-
os.chdir(self.installdir)
118-
except OSError, err:
119-
raise EasyBuildError("Failed to change %s: %s", self.installdir, err)
117+
change_dir(self.installdir)
120118

121119
# disabling templating is required here to support legacy string templates like name/version
122120
self.cfg.enable_templating = False

easybuild/tools/filetools.py

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,28 @@ def remove_file(path):
186186
raise EasyBuildError("Failed to remove %s: %s", path, err)
187187

188188

189+
def change_dir(path):
190+
"""
191+
Change to directory at specified location.
192+
193+
:param path: location to change to
194+
:return: previous location we were in
195+
"""
196+
# determining the current working directory can fail if we're in a non-existing directory
197+
try:
198+
cwd = os.getcwd()
199+
except OSError as err:
200+
_log.debug("Failed to determine current working directory (but proceeding anyway: %s", err)
201+
cwd = None
202+
203+
try:
204+
os.chdir(path)
205+
except OSError as err:
206+
raise EasyBuildError("Failed to change from %s to %s: %s", cwd, path, err)
207+
208+
return cwd
209+
210+
189211
def extract_file(fn, dest, cmd=None, extra_options=None, overwrite=False, forced=False):
190212
"""
191213
Extract file at given path to specified directory
@@ -206,11 +228,8 @@ def extract_file(fn, dest, cmd=None, extra_options=None, overwrite=False, forced
206228
abs_dest = os.path.abspath(dest)
207229

208230
# change working directory
209-
try:
210-
_log.debug("Unpacking %s in directory %s.", fn, abs_dest)
211-
os.chdir(abs_dest)
212-
except OSError, err:
213-
raise EasyBuildError("Can't change to directory %s: %s", abs_dest, err)
231+
_log.debug("Unpacking %s in directory %s.", fn, abs_dest)
232+
change_dir(abs_dest)
214233

215234
if not cmd:
216235
cmd = extract_cmd(fn, overwrite=overwrite)
@@ -595,10 +614,7 @@ def get_local_dirs_purged():
595614
if not os.path.isdir(new_dir):
596615
break
597616

598-
try:
599-
os.chdir(new_dir)
600-
except OSError, err:
601-
raise EasyBuildError("Changing to dir %s from current dir %s failed: %s", new_dir, os.getcwd(), err)
617+
change_dir(new_dir)
602618
lst = get_local_dirs_purged()
603619

604620
# make sure it's a directory, and not a (single) file that was in a tarball for example

easybuild/tools/package/utilities.py

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242

4343
from easybuild.tools.config import PKG_TOOL_FPM, PKG_TYPE_RPM, build_option, get_package_naming_scheme, log_path
4444
from easybuild.tools.build_log import EasyBuildError
45-
from easybuild.tools.filetools import which
45+
from easybuild.tools.filetools import change_dir, which
4646
from easybuild.tools.package.package_naming_scheme.pns import PackageNamingScheme
4747
from easybuild.tools.run import run_cmd
4848
from easybuild.tools.toolchain import DUMMY_TOOLCHAIN_NAME
@@ -83,11 +83,7 @@ def package_with_fpm(easyblock):
8383
pkgtype = build_option('package_type')
8484
_log.info("Will be creating %s package(s) in %s", pkgtype, workdir)
8585

86-
try:
87-
origdir = os.getcwd()
88-
os.chdir(workdir)
89-
except OSError, err:
90-
raise EasyBuildError("Failed to chdir into workdir %s: %s", workdir, err)
86+
origdir = change_dir(workdir)
9187

9288
package_naming_scheme = ActivePNS()
9389

@@ -148,10 +144,7 @@ def package_with_fpm(easyblock):
148144

149145
_log.info("Created %s package(s) in %s", pkgtype, workdir)
150146

151-
try:
152-
os.chdir(origdir)
153-
except OSError, err:
154-
raise EasyBuildError("Failed to chdir back to %s: %s", origdir, err)
147+
change_dir(origdir)
155148

156149
return workdir
157150

test/framework/filetools.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -834,6 +834,31 @@ def test_copy_file(self):
834834
self.assertTrue(ft.read_file(to_copy) == ft.read_file(target_path))
835835
self.assertEqual(txt, '')
836836

837+
def test_change_dir(self):
838+
"""Test change_dir"""
839+
840+
prev_dir = ft.change_dir(self.test_prefix)
841+
self.assertTrue(os.path.samefile(os.getcwd(), self.test_prefix))
842+
self.assertNotEqual(prev_dir, None)
843+
844+
# prepare another directory to play around with
845+
test_path = os.path.join(self.test_prefix, 'anotherdir')
846+
ft.mkdir(test_path)
847+
848+
# check return value (previous location)
849+
prev_dir = ft.change_dir(test_path)
850+
self.assertTrue(os.path.samefile(os.getcwd(), test_path))
851+
self.assertTrue(os.path.samefile(prev_dir, self.test_prefix))
852+
853+
# check behaviour when current working directory does not exist anymore
854+
shutil.rmtree(test_path)
855+
prev_dir = ft.change_dir(self.test_prefix)
856+
self.assertTrue(os.path.samefile(os.getcwd(), self.test_prefix))
857+
self.assertEqual(prev_dir, None)
858+
859+
foo = os.path.join(self.test_prefix, 'foo')
860+
self.assertErrorRegex(EasyBuildError, "Failed to change from .* to %s" % foo, ft.change_dir, foo)
861+
837862
def test_extract_file(self):
838863
"""Test extract_file"""
839864
testdir = os.path.dirname(os.path.abspath(__file__))

0 commit comments

Comments
 (0)