summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorMassimiliano Culpo <massimiliano.culpo@googlemail.com>2017-08-21 18:20:07 +0200
committerbecker33 <becker33@llnl.gov>2017-08-21 09:20:07 -0700
commit581f70ff6f3bc13d53c98da60fa0fe50fe784f2c (patch)
treeec8f9bd311d703b69de3dd085bf76480f191330c /lib
parentbd8ac0a738ba46f773722230a1943feb33197bbb (diff)
downloadspack-581f70ff6f3bc13d53c98da60fa0fe50fe784f2c.tar.gz
spack-581f70ff6f3bc13d53c98da60fa0fe50fe784f2c.tar.bz2
spack-581f70ff6f3bc13d53c98da60fa0fe50fe784f2c.tar.xz
spack-581f70ff6f3bc13d53c98da60fa0fe50fe784f2c.zip
Added custom messages for conflicts directive. fixes #4965 (#5083)
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.
Diffstat (limited to 'lib')
-rw-r--r--lib/spack/spack/directives.py6
-rw-r--r--lib/spack/spack/spec.py28
2 files changed, 26 insertions, 8 deletions
diff --git a/lib/spack/spack/directives.py b/lib/spack/spack/directives.py
index 2e8b32e5af..2a99e171a0 100644
--- a/lib/spack/spack/directives.py
+++ b/lib/spack/spack/directives.py
@@ -263,7 +263,7 @@ def _depends_on(pkg, spec, when=None, type=None):
@directive('conflicts')
-def conflicts(conflict_spec, when=None):
+def conflicts(conflict_spec, when=None, msg=None):
"""Allows a package to define a conflict.
Currently, a "conflict" is a concretized configuration that is known
@@ -280,14 +280,16 @@ def conflicts(conflict_spec, when=None):
Args:
conflict_spec (Spec): constraint defining the known conflict
when (Spec): optional constraint that triggers the conflict
+ msg (str): optional user defined message
"""
def _execute(pkg):
# If when is not specified the conflict always holds
condition = pkg.name if when is None else when
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.append(when_spec)
+ when_spec_list.append((when_spec, msg))
return _execute
diff --git a/lib/spack/spack/spec.py b/lib/spack/spack/spec.py
index 43d57f2b98..a58e1ceb2f 100644
--- a/lib/spack/spack/spec.py
+++ b/lib/spack/spack/spec.py
@@ -1798,9 +1798,9 @@ class Spec(object):
for x in self.traverse():
for conflict_spec, when_list in x.package.conflicts.items():
if x.satisfies(conflict_spec):
- for when_spec in when_list:
+ for when_spec, msg in when_list:
if x.satisfies(when_spec):
- matches.append((x, conflict_spec, when_spec))
+ matches.append((x, conflict_spec, when_spec, msg))
if matches:
raise ConflictsInSpecError(self, matches)
@@ -3447,8 +3447,24 @@ class ConflictsInSpecError(SpecError, RuntimeError):
message = 'Conflicts in concretized spec "{0}"\n'.format(
spec.short_spec
)
- long_message = 'List of matching conflicts:\n\n'
- match_fmt = '{0}. "{1}" conflicts with "{2}" in spec "{3}"\n'
- for idx, (s, c, w) in enumerate(matches):
- long_message += match_fmt.format(idx + 1, c, w, s)
+
+ visited = set()
+
+ 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)