Skip to content

Commit ad103dc

Browse files
committed
Small refactor: add keep parameter to stage, get rid of stage.destroy call.
- package.py uses context manager more effectively. - Stage.__init__ has easier to understand method signature now. - keep can be used to override the default behavior either to keep the stage ALL the time or to delete the stage ALL the time.
1 parent 14d48eb commit ad103dc

4 files changed

Lines changed: 144 additions & 93 deletions

File tree

lib/spack/llnl/util/filesystem.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -362,8 +362,9 @@ def remove_dead_links(root):
362362

363363
def remove_linked_tree(path):
364364
"""
365-
Removes a directory and its contents. If the directory is a symlink, follows the link and removes the real
366-
directory before removing the link.
365+
Removes a directory and its contents. If the directory is a
366+
symlink, follows the link and removes the real directory before
367+
removing the link.
367368
368369
Args:
369370
path: directory to be removed

lib/spack/spack/cmd/clean.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,4 @@ def clean(parser, args):
4343
specs = spack.cmd.parse_specs(args.packages, concretize=True)
4444
for spec in specs:
4545
package = spack.repo.get(spec)
46-
package.stage.destroy()
46+
package.do_clean()

lib/spack/spack/package.py

Lines changed: 61 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,7 @@ class SomePackage(Package):
293293
294294
.. code-block:: python
295295
296+
p.do_clean() # removes the stage directory entirely
296297
p.do_restage() # removes the build directory and
297298
# re-expands the archive.
298299
@@ -455,7 +456,7 @@ def _make_stage(self):
455456
# Construct a composite stage on top of the composite FetchStrategy
456457
composite_fetcher = self.fetcher
457458
composite_stage = StageComposite()
458-
resources = self._get_resources()
459+
resources = self._get_needed_resources()
459460
for ii, fetcher in enumerate(composite_fetcher):
460461
if ii == 0:
461462
# Construct root stage first
@@ -484,12 +485,14 @@ def stage(self, stage):
484485

485486

486487
def _make_fetcher(self):
487-
# Construct a composite fetcher that always contains at least one element (the root package). In case there
488-
# are resources associated with the package, append their fetcher to the composite.
488+
# Construct a composite fetcher that always contains at least
489+
# one element (the root package). In case there are resources
490+
# associated with the package, append their fetcher to the
491+
# composite.
489492
root_fetcher = fs.for_package_version(self, self.version)
490493
fetcher = fs.FetchStrategyComposite() # Composite fetcher
491494
fetcher.append(root_fetcher) # Root fetcher is always present
492-
resources = self._get_resources()
495+
resources = self._get_needed_resources()
493496
for resource in resources:
494497
fetcher.append(resource.fetcher)
495498
return fetcher
@@ -706,6 +709,7 @@ def do_stage(self, mirror_only=False):
706709
self.stage.expand_archive()
707710
self.stage.chdir_to_source()
708711

712+
709713
def do_patch(self):
710714
"""Calls do_stage(), then applied patches to the expanded tarball if they
711715
haven't been applied already."""
@@ -798,7 +802,7 @@ def do_fake_install(self):
798802
mkdirp(self.prefix.man1)
799803

800804

801-
def _get_resources(self):
805+
def _get_needed_resources(self):
802806
resources = []
803807
# Select the resources that are needed for this build
804808
for when_spec, resource_list in self.resources.items():
@@ -816,7 +820,7 @@ def _resource_stage(self, resource):
816820

817821

818822
def do_install(self,
819-
keep_prefix=False, keep_stage=False, ignore_deps=False,
823+
keep_prefix=False, keep_stage=None, ignore_deps=False,
820824
skip_patch=False, verbose=False, make_jobs=None, fake=False):
821825
"""Called by commands to install a package and its dependencies.
822826
@@ -825,7 +829,8 @@ def do_install(self,
825829
826830
Args:
827831
keep_prefix -- Keep install prefix on failure. By default, destroys it.
828-
keep_stage -- Keep stage on successful build. By default, destroys it.
832+
keep_stage -- Set to True or false to always keep or always delete stage.
833+
By default, stage is destroyed only if there are no exceptions.
829834
ignore_deps -- Do not install dependencies before installing this package.
830835
fake -- Don't really build -- install fake stub files instead.
831836
skip_patch -- Skip patch stage of build if True.
@@ -848,32 +853,33 @@ def do_install(self,
848853
make_jobs=make_jobs)
849854

850855
start_time = time.time()
851-
with self.stage:
852-
if not fake:
853-
if not skip_patch:
854-
self.do_patch()
855-
else:
856-
self.do_stage()
857-
858-
# create the install directory. The install layout
859-
# handles this in case so that it can use whatever
860-
# package naming scheme it likes.
861-
spack.install_layout.create_install_directory(self.spec)
862-
863-
def cleanup():
864-
if not keep_prefix:
865-
# If anything goes wrong, remove the install prefix
866-
self.remove_prefix()
867-
else:
868-
tty.warn("Keeping install prefix in place despite error.",
869-
"Spack will think this package is installed." +
870-
"Manually remove this directory to fix:",
871-
self.prefix, wrap=True)
872-
873-
def real_work():
874-
try:
875-
tty.msg("Building %s" % self.name)
856+
if not fake:
857+
if not skip_patch:
858+
self.do_patch()
859+
else:
860+
self.do_stage()
861+
862+
# create the install directory. The install layout
863+
# handles this in case so that it can use whatever
864+
# package naming scheme it likes.
865+
spack.install_layout.create_install_directory(self.spec)
866+
867+
def cleanup():
868+
if not keep_prefix:
869+
# If anything goes wrong, remove the install prefix
870+
self.remove_prefix()
871+
else:
872+
tty.warn("Keeping install prefix in place despite error.",
873+
"Spack will think this package is installed." +
874+
"Manually remove this directory to fix:",
875+
self.prefix, wrap=True)
876+
877+
def real_work():
878+
try:
879+
tty.msg("Building %s" % self.name)
876880

881+
self.stage.keep = keep_stage
882+
with self.stage:
877883
# Run the pre-install hook in the child process after
878884
# the directory is created.
879885
spack.hooks.pre_install(self)
@@ -888,7 +894,7 @@ def real_work():
888894
# Save the build environment in a file before building.
889895
env_path = join_path(os.getcwd(), 'spack-build.env')
890896

891-
# This redirects I/O to a build log (and optionally to the terminal)
897+
# Redirect I/O to a build log (and optionally to the terminal)
892898
log_path = join_path(os.getcwd(), 'spack-build.out')
893899
log_file = open(log_path, 'w')
894900
with log_output(log_file, verbose, sys.stdout.isatty(), True):
@@ -908,29 +914,25 @@ def real_work():
908914
packages_dir = spack.install_layout.build_packages_path(self.spec)
909915
dump_packages(self.spec, packages_dir)
910916

911-
# On successful install, remove the stage.
912-
if not keep_stage:
913-
self.stage.destroy()
917+
# Stop timer.
918+
self._total_time = time.time() - start_time
919+
build_time = self._total_time - self._fetch_time
914920

915-
# Stop timer.
916-
self._total_time = time.time() - start_time
917-
build_time = self._total_time - self._fetch_time
921+
tty.msg("Successfully installed %s" % self.name,
922+
"Fetch: %s. Build: %s. Total: %s."
923+
% (_hms(self._fetch_time), _hms(build_time), _hms(self._total_time)))
924+
print_pkg(self.prefix)
918925

919-
tty.msg("Successfully installed %s" % self.name,
920-
"Fetch: %s. Build: %s. Total: %s."
921-
% (_hms(self._fetch_time), _hms(build_time), _hms(self._total_time)))
922-
print_pkg(self.prefix)
926+
except ProcessError as e:
927+
# Annotate with location of build log.
928+
e.build_log = log_path
929+
cleanup()
930+
raise e
923931

924-
except ProcessError as e:
925-
# Annotate with location of build log.
926-
e.build_log = log_path
927-
cleanup()
928-
raise e
929-
930-
except:
931-
# other exceptions just clean up and raise.
932-
cleanup()
933-
raise
932+
except:
933+
# other exceptions just clean up and raise.
934+
cleanup()
935+
raise
934936

935937
# Set parallelism before starting build.
936938
self.make_jobs = make_jobs
@@ -1147,6 +1149,12 @@ def do_restage(self):
11471149
"""Reverts expanded/checked out source to a pristine state."""
11481150
self.stage.restage()
11491151

1152+
1153+
def do_clean(self):
1154+
"""Removes the package's build stage and source tarball."""
1155+
self.stage.destroy()
1156+
1157+
11501158
def format_doc(self, **kwargs):
11511159
"""Wrap doc string at 72 characters and format nicely"""
11521160
indent = kwargs.get('indent', 0)

0 commit comments

Comments
 (0)