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)