Repository: spack/spack

Issue:
spack install: spec conflict error message is vague.
I recently tried to install the `hoomd-blue` package on my arch machine. I got this error:

```
spack install hoomd-blue
==> Error: Conflicts in concretized spec "hoomd-blue@2.1.6%gcc@7.2.0 build_type=RelWithDebInfo +cuda~doc+mpi arch=linux-arch-x86_64 /ppp75ox"
```

How do I find out what is conflicting with what?


Discussion:
If you run `spack spec hoomd-blue` are there any messages about conflicts at the end of the output? For example:

```
==> Error: Conflicts in concretized spec "hoomd-blue@2.1.6%gcc@4.6.1 build_type=RelWithDebInfo +cuda~doc+mpi arch=linux-rhel6-x86_64 /e62rtl6"

List of matching conflicts for spec:

  (the full spec)
  ...

1. "%gcc@:4.6" conflicts with "hoomd-blue"
```

When I look at the `package.py` for `hoomd-blue` I notice the following `conflicts` directive:

```
conflicts('%gcc@6.0:')
```
Okay, you're right it's `gcc@7.2.0` which is conflicting based on the response form `spack spec`:

```
1. "%gcc@6.0:" conflicts with "hoomd-blue"
```

I wonder whether this kind of information could be incorporated into the Conflicts error.
I'm self-assigning this but giving it low priority because you can get more information about the conflict with `spack spec`
Thanks @scheibelp, If I have time, I'll take a look at it too.
@scheibelp could we put a message like "for further information use spack spec" as a stopgap measure, I ran into this a couple of times already and wasn't aware that ```spack spec``` gives different feedback than the error reported by spack install

Resolving patch:
diff --git a/lib/spack/spack/cmd/__init__.py b/lib/spack/spack/cmd/__init__.py
--- a/lib/spack/spack/cmd/__init__.py
+++ b/lib/spack/spack/cmd/__init__.py
@@ -127,7 +127,12 @@ def parse_specs(args, **kwargs):
         sys.exit(1)
 
     except spack.spec.SpecError as e:
-        tty.error(e.message)
+
+        msgs = [e.message]
+        if e.long_message:
+            msgs.append(e.long_message)
+
+        tty.error(*msgs)
         sys.exit(1)
 
 


Test patch:
diff --git a/lib/spack/spack/test/cmd/install.py b/lib/spack/spack/test/cmd/install.py
--- a/lib/spack/spack/test/cmd/install.py
+++ b/lib/spack/spack/test/cmd/install.py
@@ -33,7 +33,7 @@
 import spack
 import spack.cmd.install
 from spack.spec import Spec
-from spack.main import SpackCommand
+from spack.main import SpackCommand, SpackCommandError
 
 install = SpackCommand('install')
 
@@ -234,3 +234,14 @@ def test_install_overwrite(
     assert os.path.exists(spec.prefix)
     assert fs.hash_directory(spec.prefix) == expected_md5
     assert fs.hash_directory(spec.prefix) != bad_md5
+
+
+@pytest.mark.usefixtures(
+    'builtin_mock', 'mock_archive', 'mock_fetch', 'config', 'install_mockery',
+)
+def test_install_conflicts(conflict_spec):
+    # Make sure that spec with conflicts exit with 1
+    with pytest.raises(SpackCommandError):
+        install(conflict_spec)
+
+    assert install.returncode == 1
diff --git a/lib/spack/spack/test/concretize.py b/lib/spack/spack/test/concretize.py
--- a/lib/spack/spack/test/concretize.py
+++ b/lib/spack/spack/test/concretize.py
@@ -94,19 +94,6 @@ def spec(request):
     return request.param
 
 
-@pytest.fixture(
-    params=[
-        'conflict%clang',
-        'conflict%clang+foo',
-        'conflict-parent%clang',
-        'conflict-parent@0.9^conflict~foo'
-    ]
-)
-def conflict_spec(request):
-    """Spec to be concretized"""
-    return request.param
-
-
 @pytest.mark.usefixtures('config', 'builtin_mock')
 class TestConcretize(object):
     def test_concretize(self, spec):
diff --git a/lib/spack/spack/test/conftest.py b/lib/spack/spack/test/conftest.py
--- a/lib/spack/spack/test/conftest.py
+++ b/lib/spack/spack/test/conftest.py
@@ -690,3 +690,22 @@ def repo_for_pkg(self, name):
         import collections
         Repo = collections.namedtuple('Repo', ['namespace'])
         return Repo('mockrepo')
+
+##########
+# Specs of various kind
+##########
+
+
+@pytest.fixture(
+    params=[
+        'conflict%clang',
+        'conflict%clang+foo',
+        'conflict-parent%clang',
+        'conflict-parent@0.9^conflict~foo'
+    ]
+)
+def conflict_spec(request):
+    """Specs which violate constraints specified with the "conflicts"
+    directive in the "conflict" package.
+    """
+    return request.param