Repository: conan-io/conan

Issue:
[feature] Implement discoverability for [conf] items
Some usages of the new `[conf]` construct are starting to be instrumented throughout the codebase. Currently, it's primarily in generators and other experimental places. While it's still early for `conf`, I think we should consider providing a good experience for users to print out all available `conf` items , current values, etc.  

Also, I think we should do something different from `conan config get`, which prints the config file and doesn't reflect environment variables, and doesn't show a comprehensive list of settings which can be set. Instead, I suggest doing something similar to `argparse`, where every possible `conf` item within the codebase is declared very early on in the main setup.  Such a strategy presents some significant challenges. For example, the actual values of the variables are reconciled as "instances" per-package during various different times.  Still, perhaps it's possible.  Another strategy might be annotations. 

While I don't know all the options for implementing, I still want to suggest the feature be considered and looked into.  We keep adding new `[conf]` items in each new release of Conan.  I feel that as users get used to adding `conf` items to profiles, it will become increasingly annoying for users to figure out what all the possible `conf` items are.  They'll have to check their Conan version, then go to the specific version of the docs, and then search the docs to find out what `conf` items are available.  Exposing them at the CLI for discovery similar to `conan --help` and `conan install --help` seems a much better pattern if it can be implemented.

- [x] I've read the [CONTRIBUTING guide](https://github.com/conan-io/conan/blob/develop/.github/CONTRIBUTING.md).



Discussion:
Lets implement something very straightforward to start with:

- No magic: direct explicit listing of tools and core configurations in a single, centralized place, with its documentation there, manually added by us.
- The command ``conan config list/get/whatever`` would just list it, in a nice group and order

Lets keep potential validation for later, lets add the definition and help (and list it also in docs.conan.io)
We have two different conf levels, one for profiles and the global.

I think we just need to update profile command to show [conf] section, and for global conf, we can adapt conan config command.
It doesn't matter the origin, user wants to know all the possible configurations that they can apply, and what they mean/do. If they can/need to go in the global conf or in the profile, will be defined by its name, like ``core.xxxx`` or ``tools.xxxx``. So just 1 single command to list all existing possible configurations, not all active/used configuration.
Understood.

Resolving patch:
diff --git a/conans/client/command.py b/conans/client/command.py
--- a/conans/client/command.py
+++ b/conans/client/command.py
@@ -22,6 +22,7 @@
     ConanMigrationError
 from conans.model.ref import ConanFileReference, PackageReference, get_reference_fields, \
     check_valid_ref
+from conans.model.conf import DEFAULT_CONFIGURATION
 from conans.util.config_parser import get_bool_from_text
 from conans.util.files import exception_message_safe
 from conans.util.files import save
@@ -562,6 +563,7 @@ def config(self, *args):
         rm_subparser = subparsers.add_parser('rm', help='Remove an existing config element')
         set_subparser = subparsers.add_parser('set', help='Set a value for a configuration item')
         init_subparser = subparsers.add_parser('init', help='Initializes Conan configuration files')
+        list_subparser = subparsers.add_parser('list', help='List Conan configuration properties')
 
         get_subparser.add_argument("item", nargs="?", help="Item to print")
         home_subparser.add_argument("-j", "--json", default=None, action=OnceArgument,
@@ -627,6 +629,10 @@ def config(self, *args):
                                               target_folder=args.target_folder)
         elif args.subcommand == 'init':
             return self._conan.config_init(force=args.force)
+        elif args.subcommand == "list":
+            self._out.info("Supported Conan *experimental* conan.conf properties:")
+            for key, value in DEFAULT_CONFIGURATION.items():
+                self._out.writeln("{}: {}".format(key, value))
 
     def info(self, *args):
         """
diff --git a/conans/model/conf.py b/conans/model/conf.py
--- a/conans/model/conf.py
+++ b/conans/model/conf.py
@@ -3,6 +3,27 @@
 from conans.errors import ConanException
 
 
+DEFAULT_CONFIGURATION = {
+    "core.required_conan_version": "Will raise if the current Conan version does not match the defined version range.",
+    "core.package_id.msvc_visual_incompatible": "Allows opting-out the fallback from the new msvc compiler to the Visual Studio compiler existing binaries",
+    "tools.microsoft.msbuild:verbosity": "Verbosity level for MSBuild: 'Quiet', 'Minimal', 'Normal', 'Detailed', 'Diagnostic'",
+    "tools.microsoft.msbuild:max_cpu_count": "Argument for the /m (/maxCpuCount) when running MSBuild",
+    "tools.microsoft.msbuild:vs_version": "Defines the compiler version when using using the new msvc compiler",
+    "tools.microsoft.msbuilddeps:exclude_code_analysis": "Suppress MSBuild code analysis for patterns",
+    "tools.microsoft.msbuildtoolchain:compile_options": "Dictionary with MSBuild compiler options",
+    "tools.build:processes": "Default jobs number",
+    "tools.ninja:jobs": "Argument for the --jobs parameter when running Ninja generator",
+    "tools.gnu.make:jobs": "Argument for the -j parameter when running Make generator",
+    "tools.gnu:make_program": "Indicate path to make program",
+    "tools.env.virtualenv:auto_use": "Automatically activate virtualenvs when changing into a directory",
+    "tools.cmake.cmaketoolchain:msvc_parallel_compile": "Argument for the /MP when running msvc",
+    "tools.cmake.cmaketoolchain:find_package_prefer_config": "Argument for the CMAKE_FIND_PACKAGE_PREFER_CONFIG",
+    "tools.android:ndk_path": "Argument for the CMAKE_ANDROID_NDK",
+    "tools.files.download:retry": "Number of retries in case of failure when downloading",
+    "tools.files.download:retry_wait": "Seconds to wait between download attempts",
+}
+
+
 class _ConfModule(object):
     """
     a dictionary of key: values for each config property of a module


Test patch:
diff --git a/conans/test/integration/command/config_test.py b/conans/test/integration/command/config_test.py
--- a/conans/test/integration/command/config_test.py
+++ b/conans/test/integration/command/config_test.py
@@ -2,6 +2,7 @@
 import os
 import unittest
 import six
+from parameterized.parameterized import parameterized
 
 from conans.errors import ConanException
 from conans.test.assets.genconanfile import GenConanfile
@@ -9,6 +10,7 @@
 from conans.util.files import load, save_append
 from conans.test.utils.test_files import temp_folder
 from conans.client.tools import environment_append
+from conans.model.conf import DEFAULT_CONFIGURATION
 
 
 class ConfigTest(unittest.TestCase):
@@ -164,3 +166,11 @@ def test_init_overwrite(self):
     def _assert_dict_subset(self, expected, actual):
         actual = {k: v for k, v in actual.items() if k in expected}
         self.assertDictEqual(expected, actual)
+
+    def test_config_list(self):
+        """ config list MUST show all configuration available for global.conf
+        """
+        self.client.run('config list')
+        self.assertIn("Supported Conan *experimental* conan.conf properties:", self.client.out)
+        for key, value in DEFAULT_CONFIGURATION.items():
+            self.assertIn("{}: {}".format(key, value), self.client.out)