Repository: conan-io/conan

Issue:
[feature] JSON output for `conan config home`
The command `conan config home` returns the directory where the config resides. Within our CI we use this to clean up before doing `conan config install ...`. Right now we parse the output of that command, but this could be errorprone as outputs sometimes change or are extended with additional information.

This feature request ist about adding a `--json` parameter like all the other commands have.

- [x] I've read the [CONTRIBUTING guide](https://github.com/conan-io/conan/blob/develop/.github/CONTRIBUTING.md).



Discussion:
I'd like to work on this.

Resolving patch:
diff --git a/conans/client/command.py b/conans/client/command.py
--- a/conans/client/command.py
+++ b/conans/client/command.py
@@ -511,15 +511,15 @@ def config(self, *args):
         subparsers.required = True
 
         get_subparser = subparsers.add_parser('get', help='Get the value of configuration item')
-        subparsers.add_parser('home', help='Retrieve the Conan home directory')
+        home_subparser = subparsers.add_parser('home', help='Retrieve the Conan home directory')
         install_subparser = subparsers.add_parser('install', help='Install a full configuration '
                                                                   'from a local or remote zip file')
         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')
 
-        rm_subparser.add_argument("item", help="Item to remove")
         get_subparser.add_argument("item", nargs="?", help="Item to print")
-        set_subparser.add_argument("item", help="'item=value' to set")
+        home_subparser.add_argument("-j", "--json", default=None, action=OnceArgument,
+                                    help='json file path where the config home will be written to')
         install_subparser.add_argument("item", nargs="?",
                                        help="git repository, local folder or zip file (local or "
                                        "http) where the configuration is stored")
@@ -535,6 +535,8 @@ def config(self, *args):
                                        'specified origin')
         install_subparser.add_argument("-tf", "--target-folder",
                                        help='Install to that path in the conan cache')
+        rm_subparser.add_argument("item", help="Item to remove")
+        set_subparser.add_argument("item", help="'item=value' to set")
 
         args = parser.parse_args(*args)
 
@@ -554,6 +556,8 @@ def config(self, *args):
         elif args.subcommand == "home":
             conan_home = self._conan.config_home()
             self._out.info(conan_home)
+            if args.json:
+                self._outputer.json_output({"home": conan_home}, args.json, os.getcwd())
             return conan_home
         elif args.subcommand == "install":
             verify_ssl = get_bool_from_text(args.verify_ssl)


Test patch:
diff --git a/conans/test/functional/command/config_test.py b/conans/test/functional/command/config_test.py
--- a/conans/test/functional/command/config_test.py
+++ b/conans/test/functional/command/config_test.py
@@ -1,3 +1,4 @@
+import json
 import os
 import unittest
 import six
@@ -98,6 +99,9 @@ def missing_subarguments_test(self):
     def test_config_home_default(self):
         self.client.run("config home")
         self.assertIn(self.client.cache.cache_folder, self.client.out)
+        self.client.run("config home --json home.json")
+        self._assert_dict_subset({"home": self.client.cache.cache_folder},
+                                 json.loads(self.client.load("home.json")))
 
     def test_config_home_custom_home_dir(self):
         cache_folder = os.path.join(temp_folder(), "custom")
@@ -105,9 +109,15 @@ def test_config_home_custom_home_dir(self):
             client = TestClient(cache_folder=cache_folder)
             client.run("config home")
             self.assertIn(cache_folder, client.out)
+            client.run("config home --json home.json")
+            self._assert_dict_subset({"home": cache_folder}, json.loads(client.load("home.json")))
 
     def test_config_home_short_home_dir(self):
         cache_folder = os.path.join(temp_folder(), "custom")
         with environment_append({"CONAN_USER_HOME_SHORT": cache_folder}):
             with six.assertRaisesRegex(self, ConanException, "cannot be a subdirectory of the conan cache"):
                 TestClient(cache_folder=cache_folder)
+
+    def _assert_dict_subset(self, expected, actual):
+        actual = {k: v for k, v in actual.items() if k in expected}
+        self.assertDictEqual(expected, actual)