From 8b21e93a324bef315f6605e83c57e3ddafe9ddf8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?N=C3=ADcholas=20Kegler?= <nicholasks@gmail.com>
Date: Thu, 24 Dec 2020 11:28:47 -0300
Subject: [PATCH] Adding bare and json outputs to license command.

---
 HISTORY.rst         |  1 +
 safety/cli.py       | 15 +++++++++++++--
 safety/formatter.py | 20 ++++++++++++++++++--
 3 files changed, 32 insertions(+), 4 deletions(-)

diff --git a/HISTORY.rst b/HISTORY.rst
index be9dcdbe..14afd45c 100644
--- a/HISTORY.rst
+++ b/HISTORY.rst
@@ -6,6 +6,7 @@ History
 -------------------
 
 * Current unstable version
+* Added bare and json outputs to license command
 
 1.10.0 (2020-12-20)
 -------------------
diff --git a/safety/cli.py b/safety/cli.py
index 3510c2af..337c6508 100644
--- a/safety/cli.py
+++ b/safety/cli.py
@@ -128,6 +128,12 @@ def review(full_report, bare, file):
                    "environment variable. Default: empty")
 @click.option("--db", default="",
               help="Path to a local license database. Default: empty")
+@click.option("--json/--no-json", default=False,
+              help="Output packages licenses in JSON format. Default: --no-json")
+@click.option("--bare/--not-bare", default=False,
+              help='Output packages licenses names only. '
+                   'Useful in combination with other tools. '
+                   'Default: --not-bare')
 @click.option("--cache/--no-cache", default=True,
               help='Whether license database file should be cached.'
                    'Default: --cache')
@@ -139,7 +145,7 @@ def review(full_report, bare, file):
               help="Proxy port number --proxy-port")
 @click.option("proxyprotocol", "--proxy-protocol", "-pr", multiple=False, type=str, default='http',
               help="Proxy protocol (https or http) --proxy-protocol")
-def license(key, db, cache, files, proxyprotocol, proxyhost, proxyport):
+def license(key, db, json, bare, cache, files, proxyprotocol, proxyhost, proxyport):
 
     if files:
         packages = list(itertools.chain.from_iterable(read_requirements(f, resolve=True) for f in files))
@@ -172,7 +178,12 @@ def license(key, db, cache, files, proxyprotocol, proxyhost, proxyport):
         click.secho("Unable to load licenses database", fg="red", file=sys.stderr)
         sys.exit(-1)
     filtered_packages_licenses = get_packages_licenses(packages, licenses_db)
-    output_report = license_report(packages=packages, licenses=filtered_packages_licenses)
+    output_report = license_report(
+        packages=packages,
+        licenses=filtered_packages_licenses,
+        json_report=json,
+        bare_report=bare
+    )
     click.secho(output_report, nl=True)
 
 
diff --git a/safety/formatter.py b/safety/formatter.py
index af1e0903..8e756c97 100644
--- a/safety/formatter.py
+++ b/safety/formatter.py
@@ -236,6 +236,10 @@ class JsonReport(object):
     @staticmethod
     def render(vulns, full):
         return json.dumps(vulns, indent=4, sort_keys=True)
+    
+    @staticmethod
+    def render_licenses(packages_licenses):
+        return json.dumps(packages_licenses, indent=4, sort_keys=True)
 
 
 class BareReport(object):
@@ -244,6 +248,14 @@ class BareReport(object):
     def render(vulns, full):
         return " ".join(set([v.name for v in vulns]))
 
+    @staticmethod
+    def render_licenses(packages_licenses):
+        licenses = set([pkg_li.get('license') for pkg_li in packages_licenses])
+        if "N/A" in licenses:
+            licenses.remove("N/A")
+        sorted_licenses = sorted(licenses)
+        return " ".join(sorted_licenses)
+
 
 def get_used_db(key, db):
     key = key if key else os.environ.get("SAFETY_API_KEY", False)
@@ -266,9 +278,13 @@ def report(vulns, full=False, json_report=False, bare_report=False, checked_pack
     return BasicReport.render(vulns, full=full, checked_packages=checked_packages, used_db=used_db)
 
 
-def license_report(packages, licenses):
-    size = get_terminal_size()
+def license_report(packages, licenses, json_report=False, bare_report=False):
+    if json_report:
+        return JsonReport.render_licenses(packages_licenses=licenses)
+    elif bare_report:
+        return BareReport.render_licenses(packages_licenses=licenses)
 
+    size = get_terminal_size()
     if size.columns >= 80:
         return SheetReport.render_licenses(packages, licenses)
     return BasicReport.render_licenses(packages, licenses)