Repository: spack/spack

Issue:
cannot understand spack error message
On cooley.alcf.anl.gov, I was trying the following install for mfem...

```
[mcmiller@cooleylogin2 ~/spack]$ spack install mfem@3.2~debug+examples+hypre+lapack~mpfr+mpi+netcdf~openmp+petsc+suite-sparse+sundials+superlu-dist~threadsafe %gcc@4.4.7
```
And, I got back this error message...

```
==> Error: Invalid spec: 'superlu-dist@5.1.3%gcc@4.4.7~int64 arch=linux-rhel6-x86_64 ^cmake@3.8.1%gcc@4.4.7~doc+ncurses+openssl+ownlibs~qt arch=linux-rhel6-x86_64 ^hwloc^metis@5.1.0%gcc@4.4.7~debug~gdb~int64~real64+shared arch=linux-rhel6-x86_64 ^ncurses@6.0%gcc@4.4.7~symlinks arch=linux-rhel6-x86_64 ^openblas@0.2.19%gcc@4.4.7~openmp+pic+shared arch=linux-rhel6-x86_64 ^openmpi@2.1.1%gcc@4.4.7~cuda fabrics=verbs ~java schedulers= ~sqlite3~thread_multiple+vt arch=linux-rhel6-x86_64 ^openssl@1.0.2k%gcc@4.4.7 arch=linux-rhel6-x86_64 ^parmetis@4.0.3%gcc@4.4.7~debug~gdb+shared arch=linux-rhel6-x86_64 ^pkg-config@0.29.2%gcc@4.4.7+internal_glib arch=linux-rhel6-x86_64 ^zlib@1.2.11%gcc@4.4.7+pic+shared arch=linux-rhel6-x86_64'. Package superlu-dist requires version develop, but spec asked for 5.1.3
```

First, I didn't ask for any particular version of superlu-dist, but this error message seems to suggest I asked for version `develop`. Next, whether I put `@develop` or `@5.1.3` after `superlu-dist` in the above command, that doesn't change behavior. How do I fix this?


cannot understand spack error message
On cooley.alcf.anl.gov, I was trying the following install for mfem...

```
[mcmiller@cooleylogin2 ~/spack]$ spack install mfem@3.2~debug+examples+hypre+lapack~mpfr+mpi+netcdf~openmp+petsc+suite-sparse+sundials+superlu-dist~threadsafe %gcc@4.4.7
```
And, I got back this error message...

```
==> Error: Invalid spec: 'superlu-dist@5.1.3%gcc@4.4.7~int64 arch=linux-rhel6-x86_64 ^cmake@3.8.1%gcc@4.4.7~doc+ncurses+openssl+ownlibs~qt arch=linux-rhel6-x86_64 ^hwloc^metis@5.1.0%gcc@4.4.7~debug~gdb~int64~real64+shared arch=linux-rhel6-x86_64 ^ncurses@6.0%gcc@4.4.7~symlinks arch=linux-rhel6-x86_64 ^openblas@0.2.19%gcc@4.4.7~openmp+pic+shared arch=linux-rhel6-x86_64 ^openmpi@2.1.1%gcc@4.4.7~cuda fabrics=verbs ~java schedulers= ~sqlite3~thread_multiple+vt arch=linux-rhel6-x86_64 ^openssl@1.0.2k%gcc@4.4.7 arch=linux-rhel6-x86_64 ^parmetis@4.0.3%gcc@4.4.7~debug~gdb+shared arch=linux-rhel6-x86_64 ^pkg-config@0.29.2%gcc@4.4.7+internal_glib arch=linux-rhel6-x86_64 ^zlib@1.2.11%gcc@4.4.7+pic+shared arch=linux-rhel6-x86_64'. Package superlu-dist requires version develop, but spec asked for 5.1.3
```

First, I didn't ask for any particular version of superlu-dist, but this error message seems to suggest I asked for version `develop`. Next, whether I put `@develop` or `@5.1.3` after `superlu-dist` in the above command, that doesn't change behavior. How do I fix this?




Discussion:
that looks similar to conretization bug i had to workaround here https://github.com/LLNL/spack/pull/4735/commits/1479eab6ac8548b85ea5242d176d20643b8f2666

but you are certainly NOT using spack's main branch as 

```
$ spack spec mfem@3.2~debug+examples+hypre+lapack~mpfr+mpi+netcdf~openmp+petsc+suite-sparse+sundials+superlu-dist~threadsafe
Input spec
--------------------------------
mfem@3.2~debug+examples+hypre+lapack~mpfr+mpi+netcdf~openmp+petsc+suite-sparse+sundials+superlu-dist~threadsafe

Normalized
--------------------------------
==> Error: Package mfem has no variant set(['threadsafe', 'sundials', 'petsc', 'examples', 'openmp', 'mpfr'])!
```
The problem, I think, is that you *ask indirectly*  for both versions. What I mean is that two or more  variants in the spec you ask for imply both versions of `superlu-dist`. 

This can be nasty to track down in particular for packages that have lots of dependencies - currently you need to inspect them manually for inconsistencies. If I remember it well we had similar problems some time ago with `<something>+X` that implied at concretization time both `<something-else>~X` and `<something-else>+X`. Maybe @adamjstewart can tell you more about that.

I agree that the message in case of long specs is not particulary useful. In your case it seems to suggest that the concretization algorithm already attached `superlu-dist@develop` to your spec, and then something else requires `superlu-dist@5.1.3`. I don't know if we can easily go as far as showing in the error message the chain of deductions that the concretizer applied, but maybe pretty printing the spec so that it is shown like:
```console
hdf5@1.10.1%gcc@4.8+cxx~debug+fortran+mpi+pic+shared~szip~threadsafe arch=linux-ubuntu14-x86_64 
    ^openmpi@2.1.1%gcc@4.8~cuda fabrics= ~java schedulers= ~sqlite3~thread_multiple+vt arch=linux-ubuntu14-x86_64 
        ^hwloc@1.11.7%gcc@4.8~cuda+libxml2+pci arch=linux-ubuntu14-x86_64 
            ^libpciaccess@0.13.5%gcc@4.8 arch=linux-ubuntu14-x86_64 
                ^libtool@2.4.6%gcc@4.8 arch=linux-ubuntu14-x86_64 
                    ^m4@1.4.18%gcc@4.8+sigsegv arch=linux-ubuntu14-x86_64 
                        ^libsigsegv@2.11%gcc@4.8 arch=linux-ubuntu14-x86_64 
                ^pkg-config@0.29.2%gcc@4.8+internal_glib arch=linux-ubuntu14-x86_64 
                ^util-macros@1.19.1%gcc@4.8 arch=linux-ubuntu14-x86_64 
            ^libxml2@2.9.4%gcc@4.8~python arch=linux-ubuntu14-x86_64 
                ^xz@5.2.3%gcc@4.8 arch=linux-ubuntu14-x86_64 
                ^zlib@1.2.11%gcc@4.8+pic+shared arch=linux-ubuntu14-x86_64 
```
can help already in making it more readable and will give users a better idea where to start looking. 
@davydden but you are certainly NOT using spack's main branch as

Yes, correct. I am using the more variants for mfem PR (which I see @adamjstewart just merged today...Thanks Adam)...

Github question...I dunno but is there an easy way for another Spack developer to get a branch created for a PR on a forked repo? I mean, I don't think the `mfem_variants` branch is actually visible in the main Spack repo, is it?
@markcmiller86 You can either add the 3rd repo (at which point you have access to all its branches):
```
git remote add <name> <url>
```
of if the branch you are interested in is in a PR you can:
```
git fetch upstream pull/3183/head:PR/3183
git checkout PR/3183
```
(assuming `upstream` is the main repository).
that looks similar to conretization bug i had to workaround here https://github.com/LLNL/spack/pull/4735/commits/1479eab6ac8548b85ea5242d176d20643b8f2666

but you are certainly NOT using spack's main branch as 

```
$ spack spec mfem@3.2~debug+examples+hypre+lapack~mpfr+mpi+netcdf~openmp+petsc+suite-sparse+sundials+superlu-dist~threadsafe
Input spec
--------------------------------
mfem@3.2~debug+examples+hypre+lapack~mpfr+mpi+netcdf~openmp+petsc+suite-sparse+sundials+superlu-dist~threadsafe

Normalized
--------------------------------
==> Error: Package mfem has no variant set(['threadsafe', 'sundials', 'petsc', 'examples', 'openmp', 'mpfr'])!
```
The problem, I think, is that you *ask indirectly*  for both versions. What I mean is that two or more  variants in the spec you ask for imply both versions of `superlu-dist`. 

This can be nasty to track down in particular for packages that have lots of dependencies - currently you need to inspect them manually for inconsistencies. If I remember it well we had similar problems some time ago with `<something>+X` that implied at concretization time both `<something-else>~X` and `<something-else>+X`. Maybe @adamjstewart can tell you more about that.

I agree that the message in case of long specs is not particulary useful. In your case it seems to suggest that the concretization algorithm already attached `superlu-dist@develop` to your spec, and then something else requires `superlu-dist@5.1.3`. I don't know if we can easily go as far as showing in the error message the chain of deductions that the concretizer applied, but maybe pretty printing the spec so that it is shown like:
```console
hdf5@1.10.1%gcc@4.8+cxx~debug+fortran+mpi+pic+shared~szip~threadsafe arch=linux-ubuntu14-x86_64 
    ^openmpi@2.1.1%gcc@4.8~cuda fabrics= ~java schedulers= ~sqlite3~thread_multiple+vt arch=linux-ubuntu14-x86_64 
        ^hwloc@1.11.7%gcc@4.8~cuda+libxml2+pci arch=linux-ubuntu14-x86_64 
            ^libpciaccess@0.13.5%gcc@4.8 arch=linux-ubuntu14-x86_64 
                ^libtool@2.4.6%gcc@4.8 arch=linux-ubuntu14-x86_64 
                    ^m4@1.4.18%gcc@4.8+sigsegv arch=linux-ubuntu14-x86_64 
                        ^libsigsegv@2.11%gcc@4.8 arch=linux-ubuntu14-x86_64 
                ^pkg-config@0.29.2%gcc@4.8+internal_glib arch=linux-ubuntu14-x86_64 
                ^util-macros@1.19.1%gcc@4.8 arch=linux-ubuntu14-x86_64 
            ^libxml2@2.9.4%gcc@4.8~python arch=linux-ubuntu14-x86_64 
                ^xz@5.2.3%gcc@4.8 arch=linux-ubuntu14-x86_64 
                ^zlib@1.2.11%gcc@4.8+pic+shared arch=linux-ubuntu14-x86_64 
```
can help already in making it more readable and will give users a better idea where to start looking. 
@davydden but you are certainly NOT using spack's main branch as

Yes, correct. I am using the more variants for mfem PR (which I see @adamjstewart just merged today...Thanks Adam)...

Github question...I dunno but is there an easy way for another Spack developer to get a branch created for a PR on a forked repo? I mean, I don't think the `mfem_variants` branch is actually visible in the main Spack repo, is it?
@markcmiller86 You can either add the 3rd repo (at which point you have access to all its branches):
```
git remote add <name> <url>
```
of if the branch you are interested in is in a PR you can:
```
git fetch upstream pull/3183/head:PR/3183
git checkout PR/3183
```
(assuming `upstream` is the main repository).

Resolving patch:
diff --git a/lib/spack/spack/spec.py b/lib/spack/spack/spec.py
--- a/lib/spack/spack/spec.py
+++ b/lib/spack/spack/spec.py
@@ -1985,10 +1985,19 @@ def _merge_dependency(self, dep, deptypes, visited, spec_deps,
             try:
                 changed |= spec_deps[dep.name].constrain(dep)
             except UnsatisfiableSpecError as e:
-                e.message = "Invalid spec: '%s'. "
-                e.message += "Package %s requires %s %s, but spec asked for %s"
-                e.message %= (spec_deps[dep.name], dep.name,
-                              e.constraint_type, e.required, e.provided)
+                fmt = 'An unsatisfiable {0}'.format(e.constraint_type)
+                fmt += ' constraint has been detected for spec:'
+                fmt += '\n\n{0}\n\n'.format(spec_deps[dep.name].tree(indent=4))
+                fmt += 'while trying to concretize the partial spec:'
+                fmt += '\n\n{0}\n\n'.format(self.tree(indent=4))
+                fmt += '{0} requires {1} {2} {3}, but spec asked for {4}'
+                e.message = fmt.format(
+                    self.name,
+                    dep.name,
+                    e.constraint_type,
+                    e.required,
+                    e.provided
+                )
                 raise e
 
         # Add merged spec to my deps and recurse


Test patch: