Specs add a space before dependencies (#7942)

fixes #7941

Modified string representation of Specs to add a space before deps
Unit-tests have been modified accordingly
Added a test for regression on #7941
This commit is contained in:
Massimiliano Culpo 2018-05-07 09:05:50 +02:00 committed by GitHub
parent 506f8e9f3e
commit ff3205d21e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 45 additions and 26 deletions

View file

@ -3123,7 +3123,7 @@ def cformat(self, *args, **kwargs):
return self.format(*args, **kwargs) return self.format(*args, **kwargs)
def dep_string(self): def dep_string(self):
return ''.join("^" + dep.format() for dep in self.sorted_deps()) return ''.join(" ^" + dep.format() for dep in self.sorted_deps())
def __str__(self): def __str__(self):
ret = self.format() + self.dep_string() ret = self.format() + self.dep_string()

View file

@ -524,3 +524,16 @@ def test_regression_issue_7705(self):
s.concretize() s.concretize()
assert not s.package.provides('lapack') assert not s.package.provides('lapack')
@pytest.mark.regression('7941')
def test_regression_issue_7941(self):
# The string representation of a spec containing
# an explicit multi-valued variant and a dependency
# might be parsed differently than the originating spec
s = Spec('a foobar=bar ^b')
t = Spec(str(s))
s.concretize()
t.concretize()
assert s.dag_hash() == t.dag_hash()

View file

@ -94,7 +94,7 @@ class TestSpecSyntax(object):
# Parse checks # Parse checks
# ======================================================================== # ========================================================================
def check_parse(self, expected, spec=None, remove_arch=True): def check_parse(self, expected, spec=None):
"""Assert that the provided spec is able to be parsed. """Assert that the provided spec is able to be parsed.
If this is called with one argument, it assumes that the If this is called with one argument, it assumes that the
@ -152,14 +152,18 @@ def test_anonymous_specs_with_multiple_parts(self):
self.check_parse('@4.2: languages=go') self.check_parse('@4.2: languages=go')
def test_simple_dependence(self): def test_simple_dependence(self):
self.check_parse("openmpi^hwloc") self.check_parse("openmpi ^hwloc")
self.check_parse("openmpi^hwloc^libunwind") self.check_parse("openmpi ^hwloc", "openmpi^hwloc")
self.check_parse("openmpi ^hwloc ^libunwind")
self.check_parse("openmpi ^hwloc ^libunwind",
"openmpi^hwloc^libunwind")
def test_dependencies_with_versions(self): def test_dependencies_with_versions(self):
self.check_parse("openmpi^hwloc@1.2e6") self.check_parse("openmpi ^hwloc@1.2e6")
self.check_parse("openmpi^hwloc@1.2e6:") self.check_parse("openmpi ^hwloc@1.2e6:")
self.check_parse("openmpi^hwloc@:1.4b7-rc3") self.check_parse("openmpi ^hwloc@:1.4b7-rc3")
self.check_parse("openmpi^hwloc@1.2e6:1.4b7-rc3") self.check_parse("openmpi ^hwloc@1.2e6:1.4b7-rc3")
def test_multiple_specs(self): def test_multiple_specs(self):
self.check_parse("mvapich emacs") self.check_parse("mvapich emacs")
@ -172,31 +176,33 @@ def test_multiple_specs_after_kv(self):
def test_multiple_specs_long_second(self): def test_multiple_specs_long_second(self):
self.check_parse('mvapich emacs@1.1.1%intel cflags="-O3"', self.check_parse('mvapich emacs@1.1.1%intel cflags="-O3"',
'mvapich emacs @1.1.1 %intel cflags=-O3') 'mvapich emacs @1.1.1 %intel cflags=-O3')
self.check_parse('mvapich cflags="-O3 -fPIC" emacs^ncurses%intel') self.check_parse('mvapich cflags="-O3 -fPIC" emacs ^ncurses%intel')
self.check_parse('mvapich cflags="-O3 -fPIC" emacs ^ncurses%intel',
'mvapich cflags="-O3 -fPIC" emacs^ncurses%intel')
def test_full_specs(self): def test_full_specs(self):
self.check_parse( self.check_parse(
"mvapich_foo" "mvapich_foo"
"^_openmpi@1.2:1.4,1.6%intel@12.1+debug~qt_4" " ^_openmpi@1.2:1.4,1.6%intel@12.1+debug~qt_4"
"^stackwalker@8.1_1e") " ^stackwalker@8.1_1e")
self.check_parse( self.check_parse(
"mvapich_foo" "mvapich_foo"
"^_openmpi@1.2:1.4,1.6%intel@12.1 debug=2 ~qt_4" " ^_openmpi@1.2:1.4,1.6%intel@12.1 debug=2 ~qt_4"
"^stackwalker@8.1_1e") " ^stackwalker@8.1_1e")
self.check_parse( self.check_parse(
'mvapich_foo' 'mvapich_foo'
'^_openmpi@1.2:1.4,1.6%intel@12.1 cppflags="-O3" +debug~qt_4' ' ^_openmpi@1.2:1.4,1.6%intel@12.1 cppflags="-O3" +debug~qt_4'
'^stackwalker@8.1_1e') ' ^stackwalker@8.1_1e')
self.check_parse( self.check_parse(
"mvapich_foo" "mvapich_foo"
"^_openmpi@1.2:1.4,1.6%intel@12.1 debug=2 ~qt_4" " ^_openmpi@1.2:1.4,1.6%intel@12.1 debug=2 ~qt_4"
"^stackwalker@8.1_1e arch=test-redhat6-x86_32") " ^stackwalker@8.1_1e arch=test-redhat6-x86_32")
def test_canonicalize(self): def test_canonicalize(self):
self.check_parse( self.check_parse(
"mvapich_foo" "mvapich_foo"
"^_openmpi@1.2:1.4,1.6%intel@12.1:12.6+debug~qt_4" " ^_openmpi@1.2:1.4,1.6%intel@12.1:12.6+debug~qt_4"
"^stackwalker@8.1_1e", " ^stackwalker@8.1_1e",
"mvapich_foo " "mvapich_foo "
"^_openmpi@1.6,1.2:1.4%intel@12.1:12.6+debug~qt_4 " "^_openmpi@1.6,1.2:1.4%intel@12.1:12.6+debug~qt_4 "
@ -204,21 +210,21 @@ def test_canonicalize(self):
self.check_parse( self.check_parse(
"mvapich_foo" "mvapich_foo"
"^_openmpi@1.2:1.4,1.6%intel@12.1:12.6+debug~qt_4" " ^_openmpi@1.2:1.4,1.6%intel@12.1:12.6+debug~qt_4"
"^stackwalker@8.1_1e", " ^stackwalker@8.1_1e",
"mvapich_foo " "mvapich_foo "
"^stackwalker@8.1_1e " "^stackwalker@8.1_1e "
"^_openmpi@1.6,1.2:1.4%intel@12.1:12.6~qt_4+debug") "^_openmpi@1.6,1.2:1.4%intel@12.1:12.6~qt_4+debug")
self.check_parse( self.check_parse(
"x^y@1,2:3,4%intel@1,2,3,4+a~b+c~d+e~f", "x ^y@1,2:3,4%intel@1,2,3,4+a~b+c~d+e~f",
"x ^y~f+e~d+c~b+a@4,2:3,1%intel@4,3,2,1") "x ^y~f+e~d+c~b+a@4,2:3,1%intel@4,3,2,1")
self.check_parse( self.check_parse(
"x arch=test-redhat6-None " "x arch=test-redhat6-None "
"^y arch=test-None-x86_64 " " ^y arch=test-None-x86_64 "
"^z arch=linux-None-None", " ^z arch=linux-None-None",
"x os=fe " "x os=fe "
"^y target=be " "^y target=be "
@ -226,12 +232,12 @@ def test_canonicalize(self):
self.check_parse( self.check_parse(
"x arch=test-debian6-x86_64 " "x arch=test-debian6-x86_64 "
"^y arch=test-debian6-x86_64", " ^y arch=test-debian6-x86_64",
"x os=default_os target=default_target " "x os=default_os target=default_target "
"^y os=default_os target=default_target") "^y os=default_os target=default_target")
self.check_parse("x^y", "x@: ^y@:") self.check_parse("x ^y", "x@: ^y@:")
def test_parse_errors(self): def test_parse_errors(self):
errors = ['x@@1.2', 'x ^y@@1.2', 'x@1.2::', 'x::'] errors = ['x@@1.2', 'x ^y@@1.2', 'x@1.2::', 'x::']