Skip to content

Commit

Permalink
report: spdxtagvalue: Generate license reference
Browse files Browse the repository at this point in the history
For licenses with non-spdx license formats, attach a document block
referring to the LicenseRef with some information about the license.

In this case, we just add a string that says
'Original License: <the license that the Package object has>'

For this to work, we needed a global licenses_found list and a
function that will split up the license string in the Package object,
check to see if each of those are in the licenses_found list and
if not, then add it.

Then at then end, take each of those licenses in the license_found
list and make a block of text with the required strings.

At this point, the SPDX validator seems to be happy with the output

Signed-off-by: Nisha K <nishak@vmware.com>
  • Loading branch information
Nisha K committed May 22, 2019
1 parent 29dce08 commit 99b46f3
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 3 deletions.
4 changes: 4 additions & 0 deletions tern/report/spdxtagvalue/formats.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,7 @@
# Relationship strings
contains = 'Relationship: {outer} CONTAINS {inner}'
prereq = 'Relationship: {after} HAS_PREREQUISITE {before}'

# License Reference Information
license_id = 'LicenseID: {license_ref}'
extracted_text = 'ExtractedText: <text>Original license: {orig_license}</text>'
49 changes: 46 additions & 3 deletions tern/report/spdxtagvalue/generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,16 +110,55 @@ def get_layer_relationships(layer_obj, prev_layer_spdxref=None):
return block


def get_license_ref(license):
'''Given one license, return a LicenseRef'''
return 'LicenseRef-' + license


def get_package_licenses(license_string):
'''Return a list of strings from the original license in the Package
object. This takes in the string'''
return license_string.split(' ')


def update_license_list(license_list, license_string):
'''SPDX has a LicenseRef block at the end of the document that has
all the license references in the document. To make this work,
take in a list containing all the licenses seen thus far, and a license
string from the package manager. If the individual license in the license
string is not in the list, add it'''
licenses = get_package_licenses(license_string)
for license in licenses:
if license not in license_list:
license_list.append(license)


def format_license(license_string):
'''Given a license string, return an SPDX formatted license string.
NOTE: this is a quickfix
We will split up the licenses by spaces, prepend each string with a
"LicenseRef-" and then join the strings with an " AND "'''
license_list = license_string.split(' ')
amended_license_list = ['LicenseRef-' + l for l in license_list]
license_list = get_package_licenses(license_string)
amended_license_list = [get_license_ref(l) for l in license_list]
return ' AND '.join(amended_license_list)


def get_license_block(license_list):
'''Given a list of individual licenses, return a LicenseRef block of text
this is of the format:
## License Information
LicenseID: LicenseRef-MIT
ExtractedText: <text> </text>'''
# make a list of individual licenses
block = ''
for license in license_list:
block = block + spdx_formats.license_id.format(
license_ref=get_license_ref(license)) + '\n'
block = block + spdx_formats.extracted_text.format(
orig_license=license) + '\n\n'
return block


def generate(image_obj_list):
'''Generate an SPDX document
WARNING: This assumes that the list consists of one image or the base
Expand Down Expand Up @@ -185,6 +224,7 @@ def generate(image_obj_list):
For the sake of SPDX, an image is a 'Package' which 'CONTAINS'
each layer which is also a 'Package' which 'CONTAINS' the real Package'''
report = ''
licenses_found = [] # This is needed for unrecognized license strings
image_obj = image_obj_list[0]
template = SPDX()
# The image's PackageDownloadLocation is from a container registry
Expand Down Expand Up @@ -236,13 +276,16 @@ def generate(image_obj_list):
for layer_obj in image_obj.layers:
for package_obj in layer_obj.packages:
package_dict = package_obj.to_dict(template)
# update the PackageLicenseDeclared with a LicenseRef string
if 'PackageLicenseDeclared' in package_dict.keys():
package_dict['PackageLicenseDeclared'] = format_license(
package_obj.pkg_license)
# collect all the individual licenses
update_license_list(licenses_found, package_obj.pkg_license)
report = report + get_main_block(
package_dict,
package_obj.origins.origins,
SPDXID=get_package_spdxref(package_obj),
PackageLicenseConcluded='NOASSERTION',
FilesAnalyzed='false') + '\n'
return report
return report + get_license_block(licenses_found)

0 comments on commit 99b46f3

Please sign in to comment.