Do not call sys.exit() in except block (#7659)

When an invalid spec is encountered by `parse_specs()` we now raise a
`SpackError` instead of calling `sys.exit()`
This commit is contained in:
Zack Galbreath 2018-04-04 01:22:28 -04:00 committed by Todd Gamblin
parent b1a5764956
commit f613437a44
3 changed files with 31 additions and 12 deletions

View file

@ -26,7 +26,6 @@
import os import os
import re import re
import sys
import llnl.util.tty as tty import llnl.util.tty as tty
from llnl.util.lang import attr_setdefault, index_by from llnl.util.lang import attr_setdefault, index_by
@ -38,6 +37,7 @@
import spack.config import spack.config
import spack.spec import spack.spec
import spack.store import spack.store
from spack.error import SpackError
# #
# Settings for commands that modify configuration # Settings for commands that modify configuration
@ -141,18 +141,18 @@ def parse_specs(args, **kwargs):
return specs return specs
except spack.parse.ParseError as e: except spack.spec.SpecParseError as e:
tty.error(e.message, e.string, e.pos * " " + "^") msg = e.message + "\n" + str(e.string) + "\n"
sys.exit(1) msg += (e.pos + 2) * " " + "^"
raise SpackError(msg)
except spack.spec.SpecError as e: except spack.spec.SpecError as e:
msgs = [e.message] msg = e.message
if e.long_message: if e.long_message:
msgs.append(e.long_message) msg += e.long_message
tty.error(*msgs) raise SpackError(msg)
sys.exit(1)
def elide_list(line_list, max_num=10): def elide_list(line_list, max_num=10):

View file

@ -33,8 +33,9 @@
import spack import spack
import spack.cmd.install import spack.cmd.install
import spack.package import spack.package
from spack.error import SpackError
from spack.spec import Spec from spack.spec import Spec
from spack.main import SpackCommand, SpackCommandError from spack.main import SpackCommand
install = SpackCommand('install') install = SpackCommand('install')
@ -238,11 +239,18 @@ def test_install_overwrite(
'builtin_mock', 'mock_archive', 'mock_fetch', 'config', 'install_mockery', 'builtin_mock', 'mock_archive', 'mock_fetch', 'config', 'install_mockery',
) )
def test_install_conflicts(conflict_spec): def test_install_conflicts(conflict_spec):
# Make sure that spec with conflicts exit with 1 # Make sure that spec with conflicts raises a SpackError
with pytest.raises(SpackCommandError): with pytest.raises(SpackError):
install(conflict_spec) install(conflict_spec)
assert install.returncode == 1
@pytest.mark.usefixtures(
'builtin_mock', 'mock_archive', 'mock_fetch', 'config', 'install_mockery',
)
def test_install_invalid_spec(invalid_spec):
# Make sure that invalid specs raise a SpackError
with pytest.raises(SpackError, match='Unexpected token'):
install(invalid_spec)
@pytest.mark.usefixtures('noop_install', 'config') @pytest.mark.usefixtures('noop_install', 'config')

View file

@ -709,3 +709,14 @@ def conflict_spec(request):
directive in the "conflict" package. directive in the "conflict" package.
""" """
return request.param return request.param
@pytest.fixture(
params=[
'conflict%~'
]
)
def invalid_spec(request):
"""Specs that do not parse cleanly due to invalid formatting.
"""
return request.param