summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/spack/spack/cmd/dev_build.py10
-rw-r--r--lib/spack/spack/installer.py16
-rw-r--r--lib/spack/spack/package.py6
-rw-r--r--lib/spack/spack/test/cmd/dev_build.py39
-rwxr-xr-xshare/spack/spack-completion.bash4
5 files changed, 67 insertions, 8 deletions
diff --git a/lib/spack/spack/cmd/dev_build.py b/lib/spack/spack/cmd/dev_build.py
index c1004f24b3..7f42492808 100644
--- a/lib/spack/spack/cmd/dev_build.py
+++ b/lib/spack/spack/cmd/dev_build.py
@@ -37,10 +37,15 @@ def setup_parser(subparser):
subparser.add_argument(
'-q', '--quiet', action='store_true', dest='quiet',
help="do not display verbose build output while installing")
- subparser.add_argument(
+ arguments.add_common_arguments(subparser, ['spec'])
+
+ stop_group = subparser.add_mutually_exclusive_group()
+ stop_group.add_argument(
+ '-b', '--before', type=str, dest='before', default=None,
+ help="phase to stop before when installing (default None)")
+ stop_group.add_argument(
'-u', '--until', type=str, dest='until', default=None,
help="phase to stop after when installing (default None)")
- arguments.add_common_arguments(subparser, ['spec'])
cd_group = subparser.add_mutually_exclusive_group()
arguments.add_common_arguments(cd_group, ['clean', 'dirty'])
@@ -91,4 +96,5 @@ def dev_build(self, args):
verbose=not args.quiet,
keep_stage=True, # don't remove source dir for dev build.
dirty=args.dirty,
+ stop_before=args.before,
stop_at=args.until)
diff --git a/lib/spack/spack/installer.py b/lib/spack/spack/installer.py
index 2bad1e8818..8886f3ed06 100644
--- a/lib/spack/spack/installer.py
+++ b/lib/spack/spack/installer.py
@@ -562,6 +562,8 @@ install_args_docstring = """
even with exceptions.
restage (bool): Force spack to restage the package source.
skip_patch (bool): Skip patch stage of build if True.
+ stop_before (InstallPhase): stop execution before this
+ installation phase (or None)
stop_at (InstallPhase): last installation phase to be executed
(or None)
tests (bool or list or set): False to run no tests, True to test
@@ -779,12 +781,20 @@ class PackageInstaller(object):
Ensures the package being installed has a valid last phase before
proceeding with the installation.
- The ``stop_at`` argument is removed from the installation arguments.
+ The ``stop_before`` or ``stop_at`` arguments are removed from the
+ installation arguments.
Args:
kwargs:
+ ``stop_before``': stop before execution of this phase (or None)
``stop_at``': last installation phase to be executed (or None)
"""
+ self.pkg.stop_before_phase = kwargs.pop('stop_before', None)
+ if self.pkg.stop_before_phase is not None and \
+ self.pkg.stop_before_phase not in self.pkg.phases:
+ tty.die('\'{0}\' is not an allowed phase for package {1}'
+ .format(self.pkg.stop_before_phase, self.pkg.name))
+
self.pkg.last_phase = kwargs.pop('stop_at', None)
if self.pkg.last_phase is not None and \
self.pkg.last_phase not in self.pkg.phases:
@@ -1504,8 +1514,10 @@ class PackageInstaller(object):
self._update_installed(task)
# If we installed then we should keep the prefix
+ stop_before_phase = getattr(pkg, 'stop_before_phase', None)
last_phase = getattr(pkg, 'last_phase', None)
- keep_prefix = last_phase is None or keep_prefix
+ keep_prefix = keep_prefix or \
+ (stop_before_phase is None and last_phase is None)
except spack.directory_layout.InstallDirectoryAlreadyExistsError:
tty.debug("Keeping existing install prefix in place.")
diff --git a/lib/spack/spack/package.py b/lib/spack/spack/package.py
index b8ded0364b..40384077ea 100644
--- a/lib/spack/spack/package.py
+++ b/lib/spack/spack/package.py
@@ -115,7 +115,11 @@ class InstallPhase(object):
return phase_wrapper
def _on_phase_start(self, instance):
- pass
+ # If a phase has a matching stop_before_phase attribute,
+ # stop the installation process raising a StopIteration
+ if getattr(instance, 'stop_before_phase', None) == self.name:
+ raise StopIteration('Stopping before \'{0}\' phase'
+ .format(self.name))
def _on_phase_exit(self, instance):
# If a phase has a matching last_phase attribute,
diff --git a/lib/spack/spack/test/cmd/dev_build.py b/lib/spack/spack/test/cmd/dev_build.py
index a007513067..6afd07d815 100644
--- a/lib/spack/spack/test/cmd/dev_build.py
+++ b/lib/spack/spack/test/cmd/dev_build.py
@@ -3,8 +3,9 @@
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
import os
+import pytest
import spack.spec
-from spack.main import SpackCommand
+from spack.main import SpackCommand, SpackCommandError
dev_build = SpackCommand('dev-build')
@@ -23,6 +24,22 @@ def test_dev_build_basics(tmpdir, mock_packages, install_mockery):
assert f.read() == spec.package.replacement_string
+def test_dev_build_before(tmpdir, mock_packages, install_mockery):
+ spec = spack.spec.Spec('dev-build-test-install@0.0.0').concretized()
+
+ with tmpdir.as_cwd():
+ with open(spec.package.filename, 'w') as f:
+ f.write(spec.package.original_string)
+
+ dev_build('-b', 'edit', 'dev-build-test-install@0.0.0')
+
+ assert spec.package.filename in os.listdir(os.getcwd())
+ with open(spec.package.filename, 'r') as f:
+ assert f.read() == spec.package.original_string
+
+ assert not os.path.exists(spec.prefix)
+
+
def test_dev_build_until(tmpdir, mock_packages, install_mockery):
spec = spack.spec.Spec('dev-build-test-install@0.0.0').concretized()
@@ -39,6 +56,26 @@ def test_dev_build_until(tmpdir, mock_packages, install_mockery):
assert not os.path.exists(spec.prefix)
+def test_dev_build_before_until(tmpdir, mock_packages, install_mockery):
+ spec = spack.spec.Spec('dev-build-test-install@0.0.0').concretized()
+
+ with tmpdir.as_cwd():
+ with open(spec.package.filename, 'w') as f:
+ f.write(spec.package.original_string)
+
+ with pytest.raises(SystemExit):
+ dev_build('-u', 'edit', '-b', 'edit',
+ 'dev-build-test-install@0.0.0')
+
+ with pytest.raises(SpackCommandError):
+ dev_build('-u', 'phase_that_does_not_exist',
+ 'dev-build-test-install@0.0.0')
+
+ with pytest.raises(SpackCommandError):
+ dev_build('-b', 'phase_that_does_not_exist',
+ 'dev-build-test-install@0.0.0')
+
+
def test_dev_build_fails_already_installed(tmpdir, mock_packages,
install_mockery):
spec = spack.spec.Spec('dev-build-test-install@0.0.0').concretized()
diff --git a/share/spack/spack-completion.bash b/share/spack/spack-completion.bash
index a4d59220fa..5a4fb027c9 100755
--- a/share/spack/spack-completion.bash
+++ b/share/spack/spack-completion.bash
@@ -697,7 +697,7 @@ _spack_deprecate() {
_spack_dev_build() {
if $list_options
then
- SPACK_COMPREPLY="-h --help -j --jobs -d --source-path -i --ignore-dependencies -n --no-checksum --keep-prefix --skip-patch -q --quiet -u --until --clean --dirty"
+ SPACK_COMPREPLY="-h --help -j --jobs -d --source-path -i --ignore-dependencies -n --no-checksum --keep-prefix --skip-patch -q --quiet -b --before -u --until --clean --dirty"
else
_all_packages
fi
@@ -706,7 +706,7 @@ _spack_dev_build() {
_spack_diy() {
if $list_options
then
- SPACK_COMPREPLY="-h --help -j --jobs -d --source-path -i --ignore-dependencies -n --no-checksum --keep-prefix --skip-patch -q --quiet -u --until --clean --dirty"
+ SPACK_COMPREPLY="-h --help -j --jobs -d --source-path -i --ignore-dependencies -n --no-checksum --keep-prefix --skip-patch -q --quiet -b --before -u --until --clean --dirty"
else
_all_packages
fi