summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/spack/spack/spec.py18
-rw-r--r--lib/spack/spack/test/spec_syntax.py8
2 files changed, 24 insertions, 2 deletions
diff --git a/lib/spack/spack/spec.py b/lib/spack/spack/spec.py
index 3b8ed07a83..141f6c4b62 100644
--- a/lib/spack/spack/spec.py
+++ b/lib/spack/spack/spec.py
@@ -1559,8 +1559,24 @@ class Spec(object):
def _add_dependency(self, spec, deptypes):
"""Called by the parser to add another spec as a dependency."""
if spec.name in self._dependencies:
- raise DuplicateDependencyError("Cannot depend on '%s' twice" % spec)
+ # allow redundant compatible dependency specifications
+ # depspec equality checks by name, so we need to check components
+ # separately to test whether the specs are identical
+ orig = self._dependencies[spec.name]
+ for dspec in orig:
+ if deptypes == dspec.deptypes:
+ try:
+ dspec.spec.constrain(spec)
+ return
+ except spack.error.UnsatisfiableSpecError:
+ raise DuplicateDependencyError(
+ "Cannot depend on incompatible specs '%s' and '%s'"
+ % (dspec.spec, spec)
+ )
+ else:
+ raise DuplicateDependencyError("Cannot depend on '%s' twice" % spec)
+ # create an edge and add to parent and child
self.add_dependency_edge(spec, deptypes)
def add_dependency_edge(self, dependency_spec, deptype):
diff --git a/lib/spack/spack/test/spec_syntax.py b/lib/spack/spack/test/spec_syntax.py
index ab560bed08..cf1ce971d0 100644
--- a/lib/spack/spack/test/spec_syntax.py
+++ b/lib/spack/spack/test/spec_syntax.py
@@ -293,6 +293,12 @@ class TestSpecSyntax(object):
self.check_parse("x ^y", "x@: ^y@:")
+ def test_parse_redundant_deps(self):
+ self.check_parse("x ^y@foo", "x ^y@foo ^y@foo")
+ self.check_parse("x ^y@foo+bar", "x ^y@foo ^y+bar")
+ self.check_parse("x ^y@foo+bar", "x ^y@foo+bar ^y")
+ self.check_parse("x ^y@foo+bar", "x ^y ^y@foo+bar")
+
def test_parse_errors(self):
errors = ["x@@1.2", "x ^y@@1.2", "x@1.2::", "x::"]
self._check_raises(SpecParseError, errors)
@@ -481,7 +487,7 @@ class TestSpecSyntax(object):
self._check_raises(MultipleVersionError, multiples)
def test_duplicate_dependency(self):
- self._check_raises(DuplicateDependencyError, ["x ^y ^y"])
+ self._check_raises(DuplicateDependencyError, ["x ^y@1 ^y@2"])
def test_duplicate_compiler(self):
duplicates = [