def get_image_extracted_licenses(image_obj): '''Given an image_obj, return a unique list of extractedText dictionaries that contain all the file and package license key-value pairs for a LicenseRef and its corresponding plain text. The dictionaries will contain the following information: { "extractedText": "Plain text of license", "licenseId": "Corresponding LicenseRef" }''' unique_licenses = set() for layer in image_obj.layers: # Get all of the unique file licenses, if they exist unique_licenses.update(spdx_common.get_layer_licenses(layer)) # Next, collect any package licenses not already accounted for for package in layer.packages: if package.pkg_license: unique_licenses.add(package.pkg_license) extracted_texts = [] for lic in list(unique_licenses): extracted_texts.append( json_formats.get_extracted_text_dict( extracted_text=lic, license_ref=spdx_common.get_license_ref(lic))) return extracted_texts
def get_package_dict(package, template): '''''Given a package object and its SPDX template mapping, return a SPDX JSON dictionary representation of the package. The analyzed files will go in a separate dictionary for the JSON document.''' mapping = package.to_dict(template) package_dict = { 'name': mapping['PackageName'], 'SPDXID': spdx_common.get_package_spdxref(package), 'versionInfo': mapping['PackageVersion'] if mapping['PackageVersion'] else 'NOASSERTION', 'downloadLocation': mapping['PackageDownloadLocation'] if mapping['PackageDownloadLocation'] else 'NONE', 'filesAnalyzed': 'false', # always false for packages 'licenseConcluded': 'NOASSERTION', # always NOASSERTION 'licenseDeclared': spdx_common.get_license_ref(mapping['PackageLicenseDeclared']) if mapping['PackageLicenseDeclared'] else 'NONE', 'copyrightText': mapping['PackageCopyrightText'] if mapping['PackageCopyrightText'] else 'NONE', 'comment': get_package_comment(package) } return package_dict
def get_layer_dict(layer_obj): '''Given an layer object, return a SPDX JSON/dictionary representation of the layer. An image layer in SPDX behaves like a Package. The analyzed files will go in a separate dictionary for the JSON document.''' layer_dict = { 'name': os.path.basename(layer_obj.tar_file), 'SPDXID': spdx_common.get_layer_spdxref(layer_obj), 'packageFileName': layer_obj.tar_file, 'downloadLocation': 'NONE', 'filesAnalyzed': bool(layer_obj.files_analyzed), 'checksums': [{ 'algorithm': spdx_common.get_layer_checksum(layer_obj).split(': ', maxsplit=1)[0], 'checksumValue': spdx_common.get_layer_checksum(layer_obj).split(': ')[1] }], 'licenseConcluded': 'NOASSERTION', # always NOASSERTION 'licenseDeclared': 'NOASSERTION', # always NOASSERTION 'copyrightText': 'NOASSERTION', # always NOASSERTION } # Only include layer file information if file data is available if layer_obj.files_analyzed: layer_dict['hasFiles'] = get_layer_file_data_list(layer_obj) # packageVerificationCode must be omitted if filesAnalyzed is false if layer_obj.files_analyzed: layer_dict['packageVerificationCode'] = { 'packageVerificationCodeValue': spdx_common.get_layer_verification_code(layer_obj) } # Include layer package comment only if it exists layer_pkg_comment = get_layer_package_comment(layer_obj) if layer_pkg_comment: layer_dict['comment'] = layer_pkg_comment # Include layer licenses from files only if they exist # List will be blank if no filedata information exists layer_licenses = spdx_common.get_layer_licenses(layer_obj) layer_license_refs = [] if layer_licenses: # Use the layer LicenseRef in the list instead of license expression for lic in layer_licenses: layer_license_refs.append(spdx_common.get_license_ref(lic)) layer_dict['licenseInfoFromFiles'] = layer_license_refs return layer_dict
def get_file_dict(filedata, template, layer_id): '''''Given a FileData object and its SPDX template mapping, return a SPDX JSON dictionary representation of the file. A layer_id is used to distinguish copies of the same file occuring in different places in the image''' mapping = filedata.to_dict(template) file_dict = { 'fileName': mapping['FileName'], 'SPDXID': spdx_common.get_file_spdxref(filedata, layer_id), 'checksums': [{ 'algorithm': spdx_common.get_file_checksum(filedata).split(': ')[0], 'checksumValue': spdx_common.get_file_checksum(filedata).split(': ')[1] }], 'licenseConcluded': 'NOASSERTION', # we don't provide this 'copyrightText': 'NOASSERTION' # we don't know this } # Some files may not have a fileType available if mapping['FileType']: file_dict['fileTypes'] = [mapping['FileType']] if not filedata.licenses: file_dict['licenseInfoInFiles'] = ['NONE'] else: file_license_refs = [] for lic in spdx_common.get_file_licenses(filedata): # Add the LicenseRef to the list instead of license expression file_license_refs.append(spdx_common.get_license_ref(lic)) file_dict['licenseInfoInFiles'] = file_license_refs # We only add this if there is a notice file_notice = spdx_common.get_file_notice(filedata) if file_notice: file_dict['noticeText'] = file_notice # We only add this if there is a comment file_comment = spdx_common.get_file_comment(filedata) if file_comment: file_dict['comment'] = file_comment # We only add this if there are contributors file_contributors = get_file_contributors(filedata) if file_contributors: file_dict['fileContributors'] = file_contributors return file_dict
def get_license_info_block(filedata): '''The SPDX spec asks to list of SPDX license identifiers or license reference IDs using the format: LicenseInfoInFile: <license ref>. In this case, we do not know if we are collecting SPDX license identifiers or license strings or something else. So we will create license refs here. If the licenses list is empty we will report NONE''' block = '' if not filedata.licenses: block = 'LicenseInfoInFile: NONE\n' else: for lic in spdx_common.get_file_licenses(filedata): block = block + 'LicenseInfoInFile: {}'.format( spdx_common.get_license_ref(lic)) + '\n' return block
def get_package_license_info_block(layer_obj): '''Given a layer object, return the SPDX document block with licenses from the files in the layer. Return an empty string if the files are not analyzed''' block = '' if layer_obj.files_analyzed: licenses = spdx_common.get_layer_licenses(layer_obj) if licenses: for lic in licenses: block += 'PackageLicenseInfoFromFiles: {}\n'.format( spdx_common.get_license_ref(lic)) else: block = 'PackageLicenseInfoFromFiles: NONE\n' return block
def get_image_file_license_block(image_obj): '''Given the image object, get all the licenses found for the files in the image. We will make use of some helper functions from the layer and file helpers''' block = '' licenses = set() for layer in image_obj.layers: if layer.files_analyzed: for lic in spdx_common.get_layer_licenses(layer): licenses.add(lic) for lic in licenses: block += spdx_formats.license_id.format( license_ref=spdx_common.get_license_ref(lic)) + '\n' block += spdx_formats.extracted_text.format(orig_license=lic) + '\n' return block
def get_image_packages_license_block(image_obj): '''Given the image object, get all the the licenses found for packages in the image. The SPDX spec requires that each license reference be unique for the document''' block = '' licenses = set() for layer in image_obj.layers: for package in layer.packages: if package.pkg_license: licenses.add(package.pkg_license) for lic in licenses: block += spdx_formats.license_id.format( license_ref=spdx_common.get_license_ref(lic)) + '\n' block += spdx_formats.extracted_text.format(orig_license=lic) + '\n' return block
def get_source_package_block(package_obj, template): '''Given a package object and its SPDX template mapping, return a SPDX document block for the corresponding source package. The mapping should have keys: SourcePackageName SourcePackageVersion PackageLicenseDeclared PackageCopyrightText PackageDownloadLocation''' block = '' mapping = package_obj.to_dict(template) # Source Package Name block += 'PackageName: {}\n'.format(mapping['SourcePackageName']) # Source SPDXID _, spdx_ref_src = spdx_common.get_package_spdxref(package_obj) block += 'SPDXID: {}\n'.format(spdx_ref_src) # Source Package Version if mapping['SourcePackageVersion']: block += 'PackageVersion: {}\n'.format(mapping['SourcePackageVersion']) # Package Download Location (Same as binary) if mapping['PackageDownloadLocation']: block += 'PackageDownloadLoaction: {}\n'.format( mapping['PackageDownloadLocation']) else: block += 'PackageDownloadLocation: NOASSERTION\n' # Files Analyzed (always false for packages) block += 'FilesAnalyzed: false\n' # Package License Concluded (always NOASSERTION) block += 'PackageLicenseConcluded: NOASSERTION\n' # Package License Declared (use the license ref for this) if mapping['PackageLicenseDeclared']: block += 'PackageLicenseDeclared: {}\n'.format( spdx_common.get_license_ref(mapping['PackageLicenseDeclared'])) else: block += 'PackageLicenseDeclared: NONE\n' # Package Copyright Text if mapping['PackageCopyrightText']: block += 'PackageCopyrightText:' + spdx_formats.block_text.format( message=mapping['PackageCopyrightText']) + '\n' else: block += 'PackageCopyrightText: NONE\n' # Package Comments block += spdx_formats.source_comment return block