1import datetime 2import getpass 3import json 4 5 6class SBOMWriter: 7 def __init__(self, tool, out): 8 self.out = out 9 self.tool = tool 10 11 def write_header(self, package): 12 header = [ 13 'SPDXVersion: SPDX-2.2', 14 'DataLicense: CC0-1.0', 15 'SPDXID: SPDXRef-DOCUMENT', 16 'DocumentName: %s' % package, 17 # TBD 18 # 'DocumentNamespace: https://swinslow.net/spdx-examples/example1/hello-v3 19 'Creator: Person: %s' % getpass.getuser(), 20 'Creator: Tool: %s' % self.tool, 21 datetime.datetime.utcnow().strftime('Created: %Y-%m-%d-%H:%M:%SZ'), 22 '', 23 '##### Package: %s' % package, 24 ] 25 self.out.write('\n'.join(header)) 26 27 def write_packages(self, packages): 28 for p in packages: 29 name = p.get('package_name') or '<unknown>' 30 self.out.write('\n') 31 self.out.write('SPDXID: "%s"\n' % name) 32 self.out.write(' name: "%s"\n' % name) 33 34 if p.get('package_version'): 35 self.out.write(' versionInfo: "%s"\n' % p['package_version']) 36 37 # IGNORE_COPYRIGHT: Not a copyright notice. It is a variable holding one. 38 cn = p.get('copyright_notice') 39 if cn: 40 self.out.write(' copyrightText: "%s"\n' % cn) 41 42 kinds = p.get('license_kinds') 43 if kinds: 44 self.out.write(' licenseDeclared: "%s"\n' % 45 ','.join([k['name'] for k in kinds])) 46 47 url = p.get('package_url') 48 if url: 49 self.out.write(' downloadLocation: %s\n' % url) 50 51 purl = p.get('purl') 52 if purl: 53 self.out.write(' externalRef: PACKAGE-MANAGER purl %s\n' % purl) 54