gerrit/tools/bzl/license-map.py
Yuxuan 'fishy' Wang 9d0e8eac3b bazel: generate licenses.txt
Modify license_map rule to:

- Accept more than 1 targets
- Add '--asciidoctor' option to generate asciidoctor txt file
- Add support for multiple licenses for a single target (diffy_logo)

Also add test_license.sh for license_test rule to handle special
DO_NOT_DISTRIBUTE exceptions.

TESTED:
  bazel build Documentation:licenses.txt
  bazel test gerrit-pgm:pgm_license_test
  bazel test gerrit-gwtui:ui_module_license_test

Change-Id: Ic64b227fea34882721e6e064b1520cd9a4d5d4a4
2016-09-28 04:57:42 +08:00

147 lines
4.2 KiB
Python

#!/usr/bin/env python
# reads bazel query XML files, to join target names with their licenses.
from __future__ import print_function
import argparse
from collections import defaultdict
from shutil import copyfileobj
from sys import stdout, stderr
import xml.etree.ElementTree as ET
KNOWN_PROVIDED_DEPS = [
"//lib/bouncycastle:bcpg",
"//lib/bouncycastle:bcpkix",
"//lib/bouncycastle:bcprov",
]
DO_NOT_DISTRIBUTE = "//lib:LICENSE-DO_NOT_DISTRIBUTE"
LICENSE_PREFIX = "//lib:LICENSE-"
parser = argparse.ArgumentParser()
parser.add_argument("--asciidoctor", action="store_true")
parser.add_argument("xmls", nargs="+")
args = parser.parse_args()
entries = defaultdict(list)
graph = defaultdict(list)
handled_rules = []
for xml in args.xmls:
tree = ET.parse(xml)
root = tree.getroot()
for child in root:
rule_name = child.attrib["name"]
if rule_name in handled_rules:
# already handled in other xml files
continue
handled_rules.append(rule_name)
for c in child.getchildren():
if c.tag != "rule-input":
continue
license_name = c.attrib["name"]
if LICENSE_PREFIX in license_name:
if rule_name in KNOWN_PROVIDED_DEPS:
continue
entries[rule_name].append(license_name)
graph[license_name].append(rule_name)
if len(graph[DO_NOT_DISTRIBUTE]):
print("DO_NOT_DISTRIBUTE license found in:", file=stderr)
for target in graph[DO_NOT_DISTRIBUTE]:
print(target, file=stderr)
exit(1)
if args.asciidoctor:
print(
# We don't want any blank line before "= Gerrit Code Review - Licenses"
"""= Gerrit Code Review - Licenses
Gerrit open source software is licensed under the <<Apache2_0,Apache
License 2.0>>. Executable distributions also include other software
components that are provided under additional licenses.
[[cryptography]]
== Cryptography Notice
This distribution includes cryptographic software. The country
in which you currently reside may have restrictions on the import,
possession, use, and/or re-export to another country, of encryption
software. BEFORE using any encryption software, please check
your country's laws, regulations and policies concerning the
import, possession, or use, and re-export of encryption software,
to see if this is permitted. See the
link:http://www.wassenaar.org/[Wassenaar Arrangement]
for more information.
The U.S. Government Department of Commerce, Bureau of Industry
and Security (BIS), has classified this software as Export
Commodity Control Number (ECCN) 5D002.C.1, which includes
information security software using or performing cryptographic
functions with asymmetric algorithms. The form and manner of
this distribution makes it eligible for export under the License
Exception ENC Technology Software Unrestricted (TSU) exception
(see the BIS Export Administration Regulations, Section 740.13)
for both object code and source code.
Gerrit includes an SSH daemon (Apache SSHD), to support authenticated
uploads of changes directly from `git push` command line clients.
Gerrit includes an SSH client (JSch), to support authenticated
replication of changes to remote systems, such as for automatic
updates of mirror servers, or realtime backups.
For either feature to function, Gerrit requires the
link:http://java.sun.com/javase/technologies/security/[Java Cryptography extensions]
and/or the
link:http://www.bouncycastle.org/java.html[Bouncy Castle Crypto API]
to be installed by the end-user.
== Licenses
""")
for n in sorted(graph.keys()):
if len(graph[n]) == 0:
continue
name = n[len(LICENSE_PREFIX):]
safename = name.replace(".", "_")
print()
print("[[%s]]" % safename)
print("=== " + name)
print()
for d in sorted(graph[n]):
if d.startswith("//lib:") or d.startswith("//lib/"):
p = d[len("//lib:"):]
else:
p = d[d.index(":")+1:].lower()
if "__" in p:
p = p[:p.index("__")]
print("* " + p)
print()
print("[[%s_license]]" % safename)
print("----")
with open(n[2:].replace(":", "/")) as fd:
copyfileobj(fd, stdout)
print()
print("----")
print()
print(
"""
GERRIT
------
Part of link:index.html[Gerrit Code Review]
""")
else:
for k, vs in sorted(entries.items()):
for v in vs:
print(k, v)