From d74396ad21ac30ad69fc07678b5400187bbf2a7d Mon Sep 17 00:00:00 2001
From: Harmen Stoppels <harmenstoppels@gmail.com>
Date: Wed, 12 Jan 2022 17:26:28 +0100
Subject: Do not initialize config on spack compiler list (#28042)

When `spack compiler list` is run without being restricted to a
particular scope, and no compilers are found, say that none are
available, and hint that the use should run spack compiler find to
auto detect compilers.

* Improve docs
* Check if stdin is a tty
* add a test
---
 lib/spack/docs/getting_started.rst    | 16 +++++++++-------
 lib/spack/spack/cmd/compiler.py       | 17 +++++++++++++++--
 lib/spack/spack/compilers/__init__.py |  4 ++--
 lib/spack/spack/test/cmd/compiler.py  | 11 +++++++++++
 4 files changed, 37 insertions(+), 11 deletions(-)

(limited to 'lib')

diff --git a/lib/spack/docs/getting_started.rst b/lib/spack/docs/getting_started.rst
index aa56890847..f0ee86eb72 100644
--- a/lib/spack/docs/getting_started.rst
+++ b/lib/spack/docs/getting_started.rst
@@ -271,9 +271,10 @@ Compiler configuration
 ----------------------
 
 Spack has the ability to build packages with multiple compilers and
-compiler versions. Spack searches for compilers on your machine
-automatically the first time it is run. It does this by inspecting
-your ``PATH``.
+compiler versions. Compilers can be made available to Spack by
+specifying them manually in ``compilers.yaml``, or automatically by
+running ``spack compiler find``, but for convenience Spack will
+automatically detect compilers the first time it needs them.
 
 .. _cmd-spack-compilers:
 
@@ -281,7 +282,7 @@ your ``PATH``.
 ``spack compilers``
 ^^^^^^^^^^^^^^^^^^^
 
-You can see which compilers spack has found by running ``spack
+You can see which compilers are available to Spack by running ``spack
 compilers`` or ``spack compiler list``:
 
 .. code-block:: console
@@ -320,9 +321,10 @@ An alias for ``spack compiler find``.
 ``spack compiler find``
 ^^^^^^^^^^^^^^^^^^^^^^^
 
-If you do not see a compiler in this list, but you want to use it with
-Spack, you can simply run ``spack compiler find`` with the path to
-where the compiler is installed.  For example:
+Lists the compilers currently available to Spack. If you do not see
+a compiler in this list, but you want to use it with Spack, you can
+simply run ``spack compiler find`` with the path to where the
+compiler is installed.  For example:
 
 .. code-block:: console
 
diff --git a/lib/spack/spack/cmd/compiler.py b/lib/spack/spack/cmd/compiler.py
index 3543025cc0..c3ffe7b3d8 100644
--- a/lib/spack/spack/cmd/compiler.py
+++ b/lib/spack/spack/cmd/compiler.py
@@ -146,9 +146,22 @@ def compiler_info(args):
 
 
 def compiler_list(args):
+    compilers = spack.compilers.all_compilers(scope=args.scope, init_config=False)
+
+    # If there are no compilers in any scope, and we're outputting to a tty, give a
+    # hint to the user.
+    if len(compilers) == 0:
+        if not sys.stdout.isatty():
+            return
+        msg = "No compilers available"
+        if args.scope is None:
+            msg += ". Run `spack compiler find` to autodetect compilers"
+        tty.msg(msg)
+        return
+
+    index = index_by(compilers, lambda c: (c.spec.name, c.operating_system, c.target))
+
     tty.msg("Available compilers")
-    index = index_by(spack.compilers.all_compilers(scope=args.scope),
-                     lambda c: (c.spec.name, c.operating_system, c.target))
 
     # For a container, take each element which does not evaluate to false and
     # convert it to a string. For elements which evaluate to False (e.g. None)
diff --git a/lib/spack/spack/compilers/__init__.py b/lib/spack/spack/compilers/__init__.py
index c76fb0c715..a34c9c27b5 100644
--- a/lib/spack/spack/compilers/__init__.py
+++ b/lib/spack/spack/compilers/__init__.py
@@ -300,8 +300,8 @@ def find_specs_by_arch(compiler_spec, arch_spec, scope=None, init_config=True):
                                                init_config)]
 
 
-def all_compilers(scope=None):
-    config = get_compiler_config(scope)
+def all_compilers(scope=None, init_config=True):
+    config = get_compiler_config(scope, init_config=init_config)
     compilers = list()
     for items in config:
         items = items['compiler']
diff --git a/lib/spack/spack/test/cmd/compiler.py b/lib/spack/spack/test/cmd/compiler.py
index cb04e9bd27..3808afa3a6 100644
--- a/lib/spack/spack/test/cmd/compiler.py
+++ b/lib/spack/spack/test/cmd/compiler.py
@@ -10,6 +10,7 @@ import pytest
 
 import llnl.util.filesystem
 
+import spack.compilers
 import spack.main
 import spack.version
 
@@ -271,3 +272,13 @@ def test_compiler_find_path_order(
         'f77': str(clangdir.join('first_in_path', 'gfortran-8')),
         'fc': str(clangdir.join('first_in_path', 'gfortran-8')),
     }
+
+
+def test_compiler_list_empty(no_compilers_yaml, working_env, clangdir):
+    # Spack should not automatically search for compilers when listing them and none
+    # are available. And when stdout is not a tty like in tests, there should be no
+    # output and no error exit code.
+    os.environ['PATH'] = str(clangdir)
+    out = compiler('list')
+    assert not out
+    assert compiler.returncode == 0
-- 
cgit v1.2.3-70-g09d2