1#!/usr/bin/env python3 2# Copyright 2020 Google LLC 3# 4# Licensed under the Apache License, Version 2.0 (the "License"); 5# you may not use this file except in compliance with the License. 6# You may obtain a copy of the License at 7# 8# https://www.apache.org/licenses/LICENSE-2.0 9# 10# Unless required by applicable law or agreed to in writing, software 11# distributed under the License is distributed on an "AS IS" BASIS, 12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13# See the License for the specific language governing permissions and 14# limitations under the License. 15 16"""Proof of a WORKSPACE SBOM generator. 17 18This is only a demonstration. It will be replaced with other tools. 19""" 20 21import argparse 22import codecs 23import json 24from tools import sbom 25import subprocess 26import os 27 28TOOL = 'https//github.com/bazelbuild/rules_license/tools:write_workspace_sbom' 29 30def main(): 31 parser = argparse.ArgumentParser( 32 description='Demonstraton license compliance checker') 33 34 parser.add_argument('--out', default='sbom.out', help='SBOM output') 35 args = parser.parse_args() 36 37 if "BUILD_WORKING_DIRECTORY" in os.environ: 38 os.chdir(os.environ["BUILD_WORKING_DIRECTORY"]) 39 40 external_query_process = subprocess.run( 41 ['bazel', 'query', '--output', 'streamed_jsonproto', '//external:*'], 42 stdout=subprocess.PIPE, 43 ) 44 sbom_packages = [] 45 for dep_string in external_query_process.stdout.decode('utf-8').splitlines(): 46 dep = json.loads(dep_string) 47 if dep["type"] != "RULE": 48 continue 49 50 rule = dep["rule"] 51 if rule["ruleClass"] == "http_archive": 52 sbom_package = {} 53 sbom_packages.append(sbom_package) 54 55 if "attribute" not in rule: 56 continue 57 58 attributes = {attribute["name"]: attribute for attribute in rule["attribute"]} 59 60 if "name" in attributes: 61 sbom_package["package_name"] = attributes["name"]["stringValue"] 62 63 if "url" in attributes: 64 sbom_package["package_url"] = attributes["url"]["stringValue"] 65 elif "urls" in attributes: 66 urls = attributes["urls"]["stringListValue"] 67 if urls and len(urls) > 0: 68 sbom_package["package_url"] = attributes["urls"]["stringListValue"][0] 69 70 with codecs.open(args.out, mode='w', encoding='utf-8') as out: 71 sbom_writer = sbom.SBOMWriter(TOOL, out) 72 sbom_writer.write_header(package="Bazel's Workspace SBOM") 73 sbom_writer.write_packages(packages=sbom_packages) 74 75if __name__ == '__main__': 76 main() 77