diff options
author | Sasha Smundak <asmundak@google.com> | 2022-09-17 02:38:27 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2022-09-17 02:38:27 +0000 |
commit | df3b8d7aa1d57f6ee108a023e90860f1e372cb4b (patch) | |
tree | c87a7c540efe9da13cb94870d8e09efeba88f63f /tools/checker_demo.py | |
parent | 56590b14f8ec08644614fa10ac9cdc17abd8eee9 (diff) | |
parent | e66c3e756d247487d3364ef3541618a516693f92 (diff) | |
download | bazelbuild-rules_license-df3b8d7aa1d57f6ee108a023e90860f1e372cb4b.tar.gz |
Merge remote-tracking branch 'aosp/upstream-main' into notice am: d5f1fc8147 am: 64bd397324 am: 50783bf43b am: e66c3e756dmain-16k-with-phones
Original change: https://android-review.googlesource.com/c/platform/external/bazelbuild-rules_license/+/2189019
Change-Id: Ib2a4a7e26fc3f01a1df4c32fe1c230b542a2b540
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
Diffstat (limited to 'tools/checker_demo.py')
-rw-r--r-- | tools/checker_demo.py | 129 |
1 files changed, 129 insertions, 0 deletions
diff --git a/tools/checker_demo.py b/tools/checker_demo.py new file mode 100644 index 0000000..73042aa --- /dev/null +++ b/tools/checker_demo.py @@ -0,0 +1,129 @@ +#!/usr/bin/env python3 +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Proof of concept license checker. + +This is only a demonstration. It will be replaced with other tools. +""" + +import argparse +import codecs +import json + +# Conditions allowed for all applications +_ALWAYS_ALLOWED_CONDITIONS = frozenset(['notice', 'permissive', 'unencumberd']) + + +def _get_licenses(licenses_info): + with codecs.open(licenses_info, encoding='utf-8') as licenses_file: + return json.loads(licenses_file.read()) + + +def _do_report(out, licenses): + """Produce a report showing the set of licenses being used. + + Args: + out: file object to write to + licenses: list of LicenseInfo objects + + Returns: + 0 for no restricted licenses. + """ + for lic in licenses: # using strange name lic because license is built-in + rule = lic['rule'] + for kind in lic['license_kinds']: + out.write('= %s\n kind: %s\n' % (rule, kind['target'])) + out.write(' conditions: %s\n' % kind['conditions']) + + +def _check_conditions(out, licenses, allowed_conditions): + """Check that the application does not use any disallowed licenses. + + Args: + out: file object to write to + licenses: list of LicenseInfo objects + allowed_conditions: list of allowed condition names + + Returns: + 0 for no licenses from outside allowed_conditions. + """ + err = 0 + for lic in licenses: # using strange name lic because license is built-in + rule = lic['rule'] + for kind in lic['license_kinds']: + disallowed = [] + for condition in kind['conditions']: + if condition not in allowed_conditions: + disallowed.append(condition) + if disallowed: + out.write('ERROR: %s\n' % rule) + out.write(' kind: %s\n' % kind['target']) + out.write(' conditions: %s\n' % kind['conditions']) + out.write(' disallowed condition: %s\n' % ','.join(disallowed)) + err += 1 + return err + + +def _do_copyright_notices(out, licenses): + for l in licenses: + name = l.get('package_name') or '<unknown>' + if l.get('package_version'): + name = name + "/" + l['package_version'] + # IGNORE_COPYRIGHT: Not a copyright notice. It is a variable holding one. + out.write('package(%s), copyright(%s)\n' % (name, l['copyright_notice'])) + + +def _do_licenses(out, licenses): + for lic in licenses: + path = lic['license_text'] + with codecs.open(path, encoding='utf-8') as license_file: + out.write('= %s\n' % path) + out.write(license_file.read()) + + +def main(): + parser = argparse.ArgumentParser( + description='Demonstraton license compliance checker') + + parser.add_argument('--licenses_info', + help='path to JSON file containing all license data') + parser.add_argument('--report', default='report', help='Summary report') + parser.add_argument('--copyright_notices', + help='output file of all copyright notices') + parser.add_argument('--license_texts', help='output file of all license files') + parser.add_argument('--check_conditions', action='store_true', + help='check that the dep only includes allowed license conditions') + args = parser.parse_args() + + licenses = _get_licenses(args.licenses_info) + err = 0 + with codecs.open(args.report, mode='w', encoding='utf-8') as rpt: + _do_report(rpt, licenses) + if args.check_conditions: + # TODO(aiuto): Read conditions from a file of allowed conditions for + # a specified application deployment environment. + err = _check_conditions(rpt, licenses, _ALWAYS_ALLOWED_CONDITIONS) + if args.copyright_notices: + with codecs.open( + args.copyright_notices, mode='w', encoding='utf-8') as out: + _do_copyright_notices(out, licenses) + if args.license_texts: + with codecs.open(args.license_texts, mode='w', encoding='utf-8') as out: + _do_licenses(out, licenses) + return err + + +if __name__ == '__main__': + main() |