Users can now add an optional custom message to the conflicts directive. Layout on screen has been changed to improve readability and the long spec is shown in tree format. Two conflicts in `espresso` have been modified to showcase the feature.
This commit is contained in:
parent
bd8ac0a738
commit
581f70ff6f
3 changed files with 37 additions and 10 deletions
|
@ -263,7 +263,7 @@ def _depends_on(pkg, spec, when=None, type=None):
|
||||||
|
|
||||||
|
|
||||||
@directive('conflicts')
|
@directive('conflicts')
|
||||||
def conflicts(conflict_spec, when=None):
|
def conflicts(conflict_spec, when=None, msg=None):
|
||||||
"""Allows a package to define a conflict.
|
"""Allows a package to define a conflict.
|
||||||
|
|
||||||
Currently, a "conflict" is a concretized configuration that is known
|
Currently, a "conflict" is a concretized configuration that is known
|
||||||
|
@ -280,14 +280,16 @@ def conflicts(conflict_spec, when=None):
|
||||||
Args:
|
Args:
|
||||||
conflict_spec (Spec): constraint defining the known conflict
|
conflict_spec (Spec): constraint defining the known conflict
|
||||||
when (Spec): optional constraint that triggers the conflict
|
when (Spec): optional constraint that triggers the conflict
|
||||||
|
msg (str): optional user defined message
|
||||||
"""
|
"""
|
||||||
def _execute(pkg):
|
def _execute(pkg):
|
||||||
# If when is not specified the conflict always holds
|
# If when is not specified the conflict always holds
|
||||||
condition = pkg.name if when is None else when
|
condition = pkg.name if when is None else when
|
||||||
when_spec = parse_anonymous_spec(condition, pkg.name)
|
when_spec = parse_anonymous_spec(condition, pkg.name)
|
||||||
|
|
||||||
|
# Save in a list the conflicts and the associated custom messages
|
||||||
when_spec_list = pkg.conflicts.setdefault(conflict_spec, [])
|
when_spec_list = pkg.conflicts.setdefault(conflict_spec, [])
|
||||||
when_spec_list.append(when_spec)
|
when_spec_list.append((when_spec, msg))
|
||||||
return _execute
|
return _execute
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1798,9 +1798,9 @@ def concretize(self):
|
||||||
for x in self.traverse():
|
for x in self.traverse():
|
||||||
for conflict_spec, when_list in x.package.conflicts.items():
|
for conflict_spec, when_list in x.package.conflicts.items():
|
||||||
if x.satisfies(conflict_spec):
|
if x.satisfies(conflict_spec):
|
||||||
for when_spec in when_list:
|
for when_spec, msg in when_list:
|
||||||
if x.satisfies(when_spec):
|
if x.satisfies(when_spec):
|
||||||
matches.append((x, conflict_spec, when_spec))
|
matches.append((x, conflict_spec, when_spec, msg))
|
||||||
if matches:
|
if matches:
|
||||||
raise ConflictsInSpecError(self, matches)
|
raise ConflictsInSpecError(self, matches)
|
||||||
|
|
||||||
|
@ -3447,8 +3447,24 @@ def __init__(self, spec, matches):
|
||||||
message = 'Conflicts in concretized spec "{0}"\n'.format(
|
message = 'Conflicts in concretized spec "{0}"\n'.format(
|
||||||
spec.short_spec
|
spec.short_spec
|
||||||
)
|
)
|
||||||
long_message = 'List of matching conflicts:\n\n'
|
|
||||||
match_fmt = '{0}. "{1}" conflicts with "{2}" in spec "{3}"\n'
|
visited = set()
|
||||||
for idx, (s, c, w) in enumerate(matches):
|
|
||||||
long_message += match_fmt.format(idx + 1, c, w, s)
|
long_message = ''
|
||||||
|
|
||||||
|
match_fmt_default = '{0}. "{1}" conflicts with "{2}"\n'
|
||||||
|
match_fmt_custom = '{0}. "{1}" conflicts with "{2}" [{3}]\n'
|
||||||
|
|
||||||
|
for idx, (s, c, w, msg) in enumerate(matches):
|
||||||
|
|
||||||
|
if s not in visited:
|
||||||
|
visited.add(s)
|
||||||
|
long_message += 'List of matching conflicts for spec:\n\n'
|
||||||
|
long_message += s.tree(indent=4) + '\n'
|
||||||
|
|
||||||
|
if msg is None:
|
||||||
|
long_message += match_fmt_default.format(idx + 1, c, w)
|
||||||
|
else:
|
||||||
|
long_message += match_fmt_custom.format(idx + 1, c, w, msg)
|
||||||
|
|
||||||
super(ConflictsInSpecError, self).__init__(message, long_message)
|
super(ConflictsInSpecError, self).__init__(message, long_message)
|
||||||
|
|
|
@ -75,8 +75,17 @@ class Espresso(Package):
|
||||||
patch('dspev_drv_elpa.patch', when='@6.1 ^elpa@2016.05.003')
|
patch('dspev_drv_elpa.patch', when='@6.1 ^elpa@2016.05.003')
|
||||||
|
|
||||||
# We can't ask for scalapack or elpa if we don't want MPI
|
# We can't ask for scalapack or elpa if we don't want MPI
|
||||||
conflicts('+scalapack', when='~mpi')
|
conflicts(
|
||||||
conflicts('+elpa', when='~mpi')
|
'+scalapack',
|
||||||
|
when='~mpi',
|
||||||
|
msg='scalapack is a parallel library and needs MPI support'
|
||||||
|
)
|
||||||
|
|
||||||
|
conflicts(
|
||||||
|
'+elpa',
|
||||||
|
when='~mpi',
|
||||||
|
msg='elpa is a parallel library and needs MPI support'
|
||||||
|
)
|
||||||
|
|
||||||
# Elpa is formally supported by @:5.4.0, but QE configure searches
|
# Elpa is formally supported by @:5.4.0, but QE configure searches
|
||||||
# for it in the wrong folders (or tries to download it within
|
# for it in the wrong folders (or tries to download it within
|
||||||
|
|
Loading…
Reference in a new issue