diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/spack/spack/directives.py | 6 | ||||
-rw-r--r-- | lib/spack/spack/spec.py | 28 |
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) |