Skip to content

Commit 6f0e151

Browse files
Add command line option to dump license data
Adds a new command line option: `--get-license-data` to: * Dump license data in JSON, YAML and HTML formats. * Also dumps the .LICENSE file with text and data as YAML frontmatter. * Generates an index and a static website to view the data. This is reusing code originally located at: https://github.com/nexB/scancode-licensedb Reference: #2738 Signed-off-by: Ayan Sinha Mahapatra <[email protected]>
1 parent 2861d74 commit 6f0e151

File tree

2 files changed

+92
-36
lines changed

2 files changed

+92
-36
lines changed

src/licensedcode/license_db.py

+79-36
Original file line numberDiff line numberDiff line change
@@ -22,31 +22,24 @@
2222
# either express or implied.
2323
# No content from ScanCode LicenseDB should be considered or used as legal advice.
2424
# Consult an attorney for any legal advice.
25-
#
26-
# Visit https://github.com/nexB/scancode-licensedb for support.
27-
#
28-
# ScanCode Toolkit is a free Software Composition Analysis tool from nexB Inc. and
29-
# others.
30-
# Visit https://github.com/nexB/scancode-toolkit for support and download.
3125

26+
import os
3227
import json
3328
import pathlib
3429
from datetime import datetime
30+
from os.path import dirname
31+
from os.path import join
32+
from distutils.dir_util import copy_tree
33+
3534

3635
import saneyaml
37-
from jinja2 import Environment, PackageLoader
36+
from jinja2 import Environment, FileSystemLoader
3837
from licensedcode.models import load_licenses
3938
from scancode_config import __version__ as scancode_version
4039

41-
licenses = load_licenses(with_deprecated=True)
4240

43-
# GitHub Pages support only /(root) or docs/ for the source
44-
BUILD_LOCATION = "docs"
45-
46-
env = Environment(
47-
loader=PackageLoader("app", "templates"),
48-
autoescape=True,
49-
)
41+
TEMPLATES_DIR = os.path.join(dirname(__file__), 'templates')
42+
STATIC_DIR = os.path.join(dirname(__file__), 'static')
5043

5144

5245
def write_file(path, filename, content):
@@ -63,8 +56,15 @@ def now():
6356
}
6457

6558

66-
def generate_indexes(output_path):
67-
license_list_template = env.get_template("license_list.html")
59+
def generate_indexes(output_path, environment, licenses):
60+
61+
static_dest_dir = join(output_path, 'static')
62+
if not os.path.exists(static_dest_dir):
63+
os.makedirs(static_dest_dir)
64+
65+
copy_tree(STATIC_DIR, static_dest_dir)
66+
67+
license_list_template = environment.get_template("license_list.html")
6868
index_html = license_list_template.render(
6969
**base_context,
7070
licenses=licenses,
@@ -74,50 +74,93 @@ def generate_indexes(output_path):
7474
index = [
7575
{
7676
"license_key": key,
77+
"category": license.category,
7778
"spdx_license_key": license.spdx_license_key,
7879
"other_spdx_license_keys": license.other_spdx_license_keys,
7980
"is_exception": license.is_exception,
8081
"is_deprecated": license.is_deprecated,
82+
"text": license.text,
8183
"json": f"{key}.json",
82-
"yml": f"{key}.yml",
84+
"yaml": f"{key}.yml",
8385
"html": f"{key}.html",
84-
"text": f"{key}.LICENSE",
86+
"license": f"{key}.LICENSE",
8587
}
8688
for key, license in licenses.items()
8789
]
88-
write_file(output_path, "index.json", json.dumps(index))
89-
write_file(output_path, "index.yml", saneyaml.dump(index))
90+
91+
write_file(
92+
output_path,
93+
"index.json",
94+
json.dumps(index, indent=2, sort_keys=False)
95+
)
96+
write_file(
97+
output_path,
98+
"index.yml",
99+
saneyaml.dump(index, indent=2)
100+
)
90101

91102

92-
def generate_details(output_path):
93-
license_details_template = env.get_template("license_details.html")
103+
def generate_details(output_path, environment, licenses):
104+
license_details_template = environment.get_template("license_details.html")
94105
for license in licenses.values():
95-
license_data = license.to_dict()
106+
license_data = license.to_dict(include_text=True)
96107
html = license_details_template.render(
97108
**base_context,
98109
license=license,
99110
license_data=license_data,
100111
)
101112
write_file(output_path, f"{license.key}.html", html)
102-
write_file(output_path, f"{license.key}.yml", saneyaml.dump(license_data))
103-
write_file(output_path, f"{license.key}.json", json.dumps(license_data))
104-
write_file(output_path, f"{license.key}.LICENSE", license.text)
113+
write_file(
114+
output_path,
115+
f"{license.key}.yml",
116+
saneyaml.dump(license_data, indent=2)
117+
)
118+
write_file(
119+
output_path,
120+
f"{license.key}.json",
121+
json.dumps(license_data, indent=2, sort_keys=False)
122+
)
123+
license.dump(output_path)
105124

106125

107-
def generate_help(output_path):
108-
template = env.get_template("help.html")
126+
def generate_help(output_path, environment):
127+
template = environment.get_template("help.html")
109128
html = template.render(**base_context)
110129
write_file(output_path, "help.html", html)
111130

112131

113-
def generate():
114-
root_path = pathlib.Path(BUILD_LOCATION)
132+
def generate(build_location, template_dir=TEMPLATES_DIR):
133+
134+
if not os.path.exists(build_location):
135+
os.makedirs(build_location)
136+
137+
env = Environment(
138+
loader=FileSystemLoader(template_dir),
139+
autoescape=True,
140+
)
141+
licenses = load_licenses(with_deprecated=True)
142+
143+
root_path = pathlib.Path(build_location)
115144
root_path.mkdir(parents=False, exist_ok=True)
116145

117-
generate_indexes(root_path)
118-
generate_details(root_path)
119-
generate_help(root_path)
146+
generate_indexes(output_path=root_path, environment=env, licenses=licenses)
147+
generate_details(output_path=root_path, environment=env, licenses=licenses)
148+
generate_help(output_path=root_path, environment=env)
149+
150+
151+
def dump_license_data(ctx, param, value):
152+
"""
153+
Dump license data from scancode licenses to the directory passed in from
154+
command line.
120155
156+
Dumps data in JSON, YAML and HTML formats and also dumps the .LICENSE file with
157+
the license text and the data as YAML frontmatter.
158+
"""
159+
if not value or ctx.resilient_parsing:
160+
return
121161

122-
if __name__ == "__main__":
123-
generate()
162+
import click
163+
click.echo('Dumping license data to the directory specified: ')
164+
generate(build_location=value)
165+
click.echo('Done.')
166+
ctx.exit(0)

src/licensedcode/plugin_license.py

+13
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
from functools import partial
1212

1313
import attr
14+
import click
1415
from commoncode.cliutils import MISC_GROUP
1516
from commoncode.cliutils import PluggableCommandLineOption
1617
from commoncode.cliutils import SCAN_OPTIONS_GROUP
@@ -20,6 +21,7 @@
2021
from plugincode.scan import scan_impl
2122

2223
from scancode.api import SCANCODE_LICENSEDB_URL
24+
from licensedcode.license_db import dump_license_data
2325

2426
TRACE = False
2527

@@ -139,6 +141,17 @@ class LicenseScanner(ScanPlugin):
139141
help_group=SCAN_OPTIONS_GROUP,
140142
),
141143

144+
PluggableCommandLineOption(
145+
('--get-license-data',),
146+
type=click.Path(exists=False, readable=True, file_okay=False, resolve_path=True, path_type=str),
147+
metavar='DIR',
148+
callback=dump_license_data,
149+
help='Include this directory with additional custom licenses and license rules '
150+
'in the license detection index. Creates the directory if it does not exist. ',
151+
help_group=MISC_GROUP,
152+
is_eager=True,
153+
),
154+
142155
PluggableCommandLineOption(
143156
('--reindex-licenses',),
144157
is_flag=True, is_eager=True,

0 commit comments

Comments
 (0)