Repository: conan-io/conan

Issue:
[feature] Add description field to the output of `conan info`
I've just noticed that JSON output of `conan info` does not contain `description` field:

```json
{
        "revision": "0",
        "reference": "range-v3/0.10.0@microblink/stable",
        "is_ref": true,
        "display_name": "range-v3/0.10.0@microblink/stable",
        "id": "5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9",
        "build_id": null,
        "remote": {
            "name": "microblink",
            "url": "http://artifactory.microblink.com/artifactory/api/conan/conan-local"
        },
        "url": "https://github.com/ericniebler/range-v3",
        "license": [
            "Boost Software License - Version 1.0 - August 17th, 2003"
        ],
        "recipe": "Cache",
        "binary": "Cache",
        "binary_remote": "microblink",
        "creation_date": "2019-12-07 00:36:31"
    }
```

yet, the recipe contains it:

```python
class Rangev3Conan(ConanFile):
    name = "range-v3"
    version = "0.10.0"
    license = "Boost Software License - Version 1.0 - August 17th, 2003"
    url = "https://github.com/ericniebler/range-v3"
    description = """Experimental range library for C++11/14/17"""
    # No settings/options are necessary, this is header only
    exports_sources = "include*", "LICENSE.txt", "CMakeLists.txt", "cmake/*", "Version.cmake", "version.hpp.in"
    no_copy_source = True

    def package(self):
        cmake = CMake(self)
        cmake.definitions["RANGE_V3_TESTS"] = "OFF"
        cmake.definitions["RANGE_V3_EXAMPLES"] = "OFF"
        cmake.definitions["RANGE_V3_PERF"] = "OFF"
        cmake.definitions["RANGE_V3_DOCS"] = "OFF"
        cmake.definitions["RANGE_V3_HEADER_CHECKS"] = "OFF"
        cmake.configure()
        cmake.install()

        self.copy("LICENSE.txt", dst="licenses", ignore_case=True, keep_path=False)
```

I am working on a little script that will collect all OSS packages used by the product in our company and I would like it to output the name, version, URL, license and description of each of the OSS package. Currently I can get everything except the description.

I am using conan v1.23.0.


Discussion:

Resolving patch:
diff --git a/conans/client/command.py b/conans/client/command.py
--- a/conans/client/command.py
+++ b/conans/client/command.py
@@ -583,7 +583,7 @@ def info(self, *args):
         """
 
         info_only_options = ["id", "build_id", "remote", "url", "license", "requires", "update",
-                             "required", "date", "author", "None"]
+                             "required", "date", "author", "description", "None"]
         path_only_options = ["export_folder", "build_folder", "package_folder", "source_folder"]
         str_path_only_options = ", ".join(['"%s"' % field for field in path_only_options])
         str_only_options = ", ".join(['"%s"' % field for field in info_only_options])
diff --git a/conans/client/conan_command_output.py b/conans/client/conan_command_output.py
--- a/conans/client/conan_command_output.py
+++ b/conans/client/conan_command_output.py
@@ -170,6 +170,7 @@ def _add_if_exists(attrib, as_list=False):
             _add_if_exists("homepage")
             _add_if_exists("license", as_list=True)
             _add_if_exists("author")
+            _add_if_exists("description")
             _add_if_exists("topics", as_list=True)
 
             if isinstance(ref, ConanFileReference):
diff --git a/conans/client/printer.py b/conans/client/printer.py
--- a/conans/client/printer.py
+++ b/conans/client/printer.py
@@ -98,6 +98,7 @@ def _print(it_field, show_field=None, name=None, color=Color.BRIGHT_GREEN):
                 self._out.writeln("    %s: %s" % (lead_str, licenses_str), Color.BRIGHT_GREEN)
 
             _print("author", name="Author")
+            _print("description", name="Description")
 
             if show("topics") and "topics" in it:
                 self._out.writeln("    Topics: %s" % ", ".join(it["topics"]), Color.BRIGHT_GREEN)


Test patch:
diff --git a/conans/test/functional/command/info_test.py b/conans/test/functional/command/info_test.py
--- a/conans/test/functional/command/info_test.py
+++ b/conans/test/functional/command/info_test.py
@@ -56,12 +56,16 @@ def _create(self, number, version, deps=None, deps_dev=None, export=True):
             files[CONANFILE] = files[CONANFILE].replace('version = "0.1"',
                                                         'version = "0.1"\n'
                                                         '    url= "myurl"\n'
-                                                        '    license = "MIT"')
+                                                        '    license = "MIT"\n'
+                                                        '    description = "blah"')
         else:
             files[CONANFILE] = files[CONANFILE].replace('version = "0.1"',
                                                         'version = "0.1"\n'
                                                         '    url= "myurl"\n'
-                                                        '    license = "MIT", "GPL"')
+                                                        '    license = "MIT", "GPL"\n'
+                                                        '    description = """Yo no creo en brujas,\n'
+                                                        '                 pero que las hay,\n'
+                                                        '                 las hay"""')
 
         self.client.save(files)
         if export:
@@ -293,7 +297,7 @@ def info_virtual_test(self):
         self.assertNotIn("virtual", self.client.out)
         self.assertNotIn("Required", self.client.out)
 
-    def reuse_test(self):
+    def test_reuse(self):
         self.client = TestClient()
         self._create("Hello0", "0.1")
         self._create("Hello1", "0.1", ["Hello0/0.1@lasote/stable"])
@@ -311,6 +315,7 @@ def reuse_test(self):
                 Remote: None
                 URL: myurl
                 License: MIT
+                Description: blah
                 Recipe: No remote%s
                 Binary: Missing
                 Binary remote: None
@@ -320,6 +325,7 @@ def reuse_test(self):
                 Remote: None
                 URL: myurl
                 License: MIT
+                Description: blah
                 Recipe: No remote%s
                 Binary: Missing
                 Binary remote: None
@@ -330,6 +336,9 @@ def reuse_test(self):
             conanfile.py (Hello2/0.1)
                 URL: myurl
                 Licenses: MIT, GPL
+                Description: Yo no creo en brujas,
+                             pero que las hay,
+                             las hay
                 Requires:
                     Hello1/0.1@lasote/stable""")
 
@@ -377,6 +386,25 @@ def clean_output(output):
 
         self.assertIn(expected_output, clean_output(self.client.out))
 
+        self.client.run("info . -u --only=url --only=license --only=description")
+        expected_output = textwrap.dedent(
+            """\
+            Hello0/0.1@lasote/stable
+                URL: myurl
+                License: MIT
+                Description: blah
+            Hello1/0.1@lasote/stable
+                URL: myurl
+                License: MIT
+                Description: blah
+            conanfile.py (Hello2/0.1)
+                URL: myurl
+                Licenses: MIT, GPL
+                Description: Yo no creo en brujas,
+                             pero que las hay,
+                             las hay""")
+        self.assertIn(expected_output, clean_output(self.client.out))
+
     def test_json_info_outputs(self):
         self.client = TestClient()
         self._create("LibA", "0.1")
@@ -396,6 +424,7 @@ def test_json_info_outputs(self):
         content = json.loads(load(json_file))
         self.assertEqual(content[0]["reference"], "LibA/0.1@lasote/stable")
         self.assertEqual(content[0]["license"][0], "MIT")
+        self.assertEqual(content[0]["description"], "blah")
         self.assertEqual(content[1]["url"], "myurl")
         self.assertEqual(content[1]["required_by"][0], "conanfile.py (LibD/0.1)")