Skip to content

Commit 878aafb

Browse files
authored
Use license text instead of LicenseRef if possible
Previously the `PackageLicenseDeclared` and `licenseDeclared` data for spdxtagvalue and spdxjson, respectively, were set to license reference of type LicenseRef-df8cb33 which is not informative. This change updates that data to the actual license info, f.e. MIT, in case a license is declared, or the LicenseRef-df8cb33 value if it's not Resolves #1147 Signed-off-by: Ivana Atanasova <[email protected]>
2 parents ad64968 + 00a6ac9 commit 878aafb

File tree

9 files changed

+44
-30
lines changed

9 files changed

+44
-30
lines changed

requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,4 @@ regex>=2022.3
1717
GitPython~=3.1
1818
prettytable~=3.2
1919
packageurl-python>=0.9.9
20+
license_expression>=21.6.14

tern/formats/spdx/spdx_common.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import re
1414
import uuid
1515

16+
from license_expression import get_spdx_licensing
1617
from tern.utils import constants
1718
from tern.formats.spdx.spdxtagvalue import formats as spdx_formats
1819

@@ -43,6 +44,22 @@ def get_license_ref(license_string):
4344
""" For SPDX tag-value format, return a LicenseRef string """
4445
return 'LicenseRef-' + get_string_id(license_string)
4546

47+
def is_spdx_license_expression(license_data):
48+
'''Return True if the license is a valid SPDX license expression, else
49+
return False'''
50+
licensing = get_spdx_licensing()
51+
if ',' in license_data:
52+
license_data = license_data.replace(',', ' and ')
53+
return licensing.validate(license_data).errors == []
54+
55+
# Searches for declared license data using the license_expression library
56+
def get_package_license_declared(package_license_declared):
57+
if package_license_declared:
58+
if is_spdx_license_expression(package_license_declared):
59+
return package_license_declared
60+
return get_license_ref(package_license_declared)
61+
return 'NONE'
62+
4663

4764
########################
4865
# Common Image Helpers #

tern/formats/spdx/spdxjson/file_helpers.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ def get_file_dict(filedata, template, layer_id):
5050
file_license_refs = []
5151
for lic in spdx_common.get_file_licenses(filedata):
5252
# Add the LicenseRef to the list instead of license expression
53-
file_license_refs.append(spdx_common.get_license_ref(lic))
53+
file_license_refs.append(spdx_common.get_package_license_declared(lic))
5454
file_dict['licenseInfoInFiles'] = file_license_refs
5555

5656
# We only add this if there is a notice

tern/formats/spdx/spdxjson/image_helpers.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,10 @@ def get_image_extracted_licenses(image_obj):
3131
unique_licenses.add(package.pkg_license)
3232
extracted_texts = []
3333
for lic in list(unique_licenses):
34-
extracted_texts.append(json_formats.get_extracted_text_dict(
35-
extracted_text=lic, license_ref=spdx_common.get_license_ref(
36-
lic)))
34+
if not spdx_common.is_spdx_license_expression(lic):
35+
extracted_texts.append(json_formats.get_extracted_text_dict(
36+
extracted_text=lic, license_ref=spdx_common.get_license_ref(
37+
lic)))
3738
return extracted_texts
3839

3940

tern/formats/spdx/spdxjson/layer_helpers.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,10 @@ def get_layer_extracted_licenses(layer_obj):
3939
unique_licenses.add(package.pkg_license)
4040
extracted_texts = []
4141
for lic in list(unique_licenses):
42-
extracted_texts.append(json_formats.get_extracted_text_dict(
43-
extracted_text=lic, license_ref=spdx_common.get_license_ref(
44-
lic)))
42+
if not spdx_common.is_spdx_license_expression(lic):
43+
extracted_texts.append(json_formats.get_extracted_text_dict(
44+
extracted_text=lic, license_ref=spdx_common.get_license_ref(
45+
lic)))
4546
return extracted_texts
4647

4748

tern/formats/spdx/spdxjson/package_helpers.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,8 @@ def get_source_package_dict(package, template):
3939
mapping['PackageDownloadLocation'] else 'NOASSERTION',
4040
'filesAnalyzed': False, # always false for packages
4141
'licenseConcluded': 'NOASSERTION', # always NOASSERTION
42-
'licenseDeclared': spdx_common.get_license_ref(
43-
mapping['PackageLicenseDeclared']) if
44-
mapping['PackageLicenseDeclared'] else 'NONE',
42+
'licenseDeclared': spdx_common.get_package_license_declared(
43+
mapping['PackageLicenseDeclared']),
4544
'copyrightText': mapping['PackageCopyrightText'] if
4645
mapping['PackageCopyrightText'] else'NONE',
4746
'comment': json_formats.source_package_comment
@@ -65,9 +64,8 @@ def get_package_dict(package, template):
6564
mapping['PackageDownloadLocation'] else 'NOASSERTION',
6665
'filesAnalyzed': False, # always false for packages
6766
'licenseConcluded': 'NOASSERTION', # always NOASSERTION
68-
'licenseDeclared': spdx_common.get_license_ref(
69-
mapping['PackageLicenseDeclared']) if
70-
mapping['PackageLicenseDeclared'] else 'NONE',
67+
'licenseDeclared': spdx_common.get_package_license_declared(
68+
mapping['PackageLicenseDeclared']),
7169
'copyrightText': mapping['PackageCopyrightText'] if
7270
mapping['PackageCopyrightText'] else'NONE',
7371
'comment': get_package_comment(package)

tern/formats/spdx/spdxtagvalue/file_helpers.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ def get_license_info_block(filedata):
3535
else:
3636
for lic in spdx_common.get_file_licenses(filedata):
3737
block = block + 'LicenseInfoInFile: {}'.format(
38-
spdx_common.get_license_ref(lic)) + '\n'
38+
spdx_common.get_package_license_declared(lic)) + '\n'
3939
return block
4040

4141

tern/formats/spdx/spdxtagvalue/image_helpers.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,10 @@ def get_image_packages_license_block(image_obj):
5757
if package.pkg_license:
5858
licenses.add(package.pkg_license)
5959
for lic in licenses:
60-
block += spdx_formats.license_id.format(
61-
license_ref=spdx_common.get_license_ref(lic)) + '\n'
62-
block += spdx_formats.extracted_text.format(orig_license=lic) + '\n'
60+
if not spdx_common.is_spdx_license_expression(lic):
61+
block += spdx_formats.license_id.format(
62+
license_ref=spdx_common.get_license_ref(lic)) + '\n'
63+
block += spdx_formats.extracted_text.format(orig_license=lic) + '\n'
6364
return block
6465

6566

@@ -74,9 +75,10 @@ def get_image_file_license_block(image_obj):
7475
for lic in spdx_common.get_layer_licenses(layer):
7576
licenses.add(lic)
7677
for lic in licenses:
77-
block += spdx_formats.license_id.format(
78-
license_ref=spdx_common.get_license_ref(lic)) + '\n'
79-
block += spdx_formats.extracted_text.format(orig_license=lic) + '\n'
78+
if not spdx_common.is_spdx_license_expression(lic):
79+
block += spdx_formats.license_id.format(
80+
license_ref=spdx_common.get_license_ref(lic)) + '\n'
81+
block += spdx_formats.extracted_text.format(orig_license=lic) + '\n'
8082
return block
8183

8284

tern/formats/spdx/spdxtagvalue/package_helpers.py

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,8 @@ def get_source_package_block(package_obj, template):
5555
# Package License Concluded (always NOASSERTION)
5656
block += 'PackageLicenseConcluded: NOASSERTION\n'
5757
# Package License Declared (use the license ref for this)
58-
if mapping['PackageLicenseDeclared']:
59-
block += 'PackageLicenseDeclared: {}\n'.format(
60-
spdx_common.get_license_ref(mapping['PackageLicenseDeclared']))
61-
else:
62-
block += 'PackageLicenseDeclared: NONE\n'
58+
block += 'PackageLicenseDeclared: ' + spdx_common.get_package_license_declared(
59+
mapping['PackageLicenseDeclared']) + '\n'
6360
# Package Copyright Text
6461
if mapping['PackageCopyrightText']:
6562
block += 'PackageCopyrightText:' + spdx_formats.block_text.format(
@@ -100,11 +97,8 @@ def get_package_block(package_obj, template):
10097
# Package License Concluded (always NOASSERTION)
10198
block += 'PackageLicenseConcluded: NOASSERTION\n'
10299
# Package License Declared (use the license ref for this)
103-
if mapping['PackageLicenseDeclared']:
104-
block += 'PackageLicenseDeclared: {}\n'.format(
105-
spdx_common.get_license_ref(mapping['PackageLicenseDeclared']))
106-
else:
107-
block += 'PackageLicenseDeclared: NONE\n'
100+
block += 'PackageLicenseDeclared: ' + spdx_common.get_package_license_declared(
101+
mapping['PackageLicenseDeclared']) + '\n'
108102
# Package Copyright Text
109103
if mapping['PackageCopyrightText']:
110104
block += 'PackageCopyrightText:' + spdx_formats.block_text.format(

0 commit comments

Comments
 (0)