dev-build: stop before phase (#14699)

Add `-b,--before` option to dev-build command to stop before the phase in question.
This commit is contained in:
Axel Huebl 2020-04-28 09:55:57 -07:00 committed by GitHub
parent 7670ae468f
commit 00d83cd79d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 67 additions and 8 deletions

View File

@ -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)

View File

@ -562,6 +562,8 @@ def package_id(pkg):
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 @@ def _check_last_phase(self, **kwargs):
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 @@ def install(self, **kwargs):
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.")

View File

@ -115,7 +115,11 @@ def phase_wrapper(spec, prefix):
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,

View File

@ -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()

View File

@ -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