Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(195)

Side by Side Diff: tools_webrtc/libs/generate_licenses.py

Issue 3011613002: License generation script for build_aar.py. (Closed)
Patch Set: Skip deps without license Created 3 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 #!/usr/bin/python 1 #!/usr/bin/env python
2 2
3 # Copyright 2016 The WebRTC project authors. All Rights Reserved. 3 # Copyright 2016 The WebRTC project authors. All Rights Reserved.
4 # 4 #
5 # Use of this source code is governed by a BSD-style license 5 # Use of this source code is governed by a BSD-style license
6 # that can be found in the LICENSE file in the root of the source 6 # that can be found in the LICENSE file in the root of the source
7 # tree. An additional intellectual property rights grant can be found 7 # tree. An additional intellectual property rights grant can be found
8 # in the file PATENTS. All contributing project authors may 8 # in the file PATENTS. All contributing project authors may
9 # be found in the AUTHORS file in the root of the source tree. 9 # be found in the AUTHORS file in the root of the source tree.
10 10
11 """Generates license HTML for a prebuilt version of WebRTC for iOS.""" 11 """Generates license markdown for a prebuilt version of WebRTC."""
12 12
13 import sys 13 import sys
14 14
15 import argparse 15 import argparse
16 import cgi 16 import cgi
17 import json
18 import logging
17 import os 19 import os
18 import re 20 import re
19 import textwrap
20 import subprocess 21 import subprocess
21 22
22 23
23 LIB_TO_LICENSES_DICT = { 24 LIB_TO_LICENSES_DICT = {
25 'android_tools': ['third_party/android_tools/LICENSE'],
24 'boringssl': ['third_party/boringssl/src/LICENSE'], 26 'boringssl': ['third_party/boringssl/src/LICENSE'],
25 'expat': ['third_party/expat/files/COPYING'], 27 'expat': ['third_party/expat/files/COPYING'],
28 'ijar': ['third_party/ijar/LICENSE'],
26 'jsoncpp': ['third_party/jsoncpp/LICENSE'], 29 'jsoncpp': ['third_party/jsoncpp/LICENSE'],
30 'libc++': ['buildtools/third_party/libc++/trunk/LICENSE.TXT'],
31 'libc++abi': ['buildtools/third_party/libc++abi/trunk/LICENSE.TXT'],
32 'libevent': ['base/third_party/libevent/LICENSE'],
33 'libjpeg_turbo': ['third_party/libjpeg_turbo/LICENSE.md'],
34 'libsrtp': ['third_party/libsrtp/LICENSE'],
35 'libvpx': ['third_party/libvpx/source/libvpx/LICENSE'],
36 'libyuv': ['third_party/libyuv/LICENSE'],
37 'openmax_dl': ['third_party/openmax_dl/LICENSE'],
27 'opus': ['third_party/opus/src/COPYING'], 38 'opus': ['third_party/opus/src/COPYING'],
28 'protobuf': ['third_party/protobuf/LICENSE'], 39 'protobuf': ['third_party/protobuf/LICENSE'],
29 'libsrtp': ['third_party/libsrtp/LICENSE'],
30 'usrsctp': ['third_party/usrsctp/LICENSE'], 40 'usrsctp': ['third_party/usrsctp/LICENSE'],
31 'webrtc': ['webrtc/LICENSE', 'webrtc/LICENSE_THIRD_PARTY'], 41 'webrtc': ['webrtc/LICENSE', 'webrtc/LICENSE_THIRD_PARTY'],
32 'libvpx': ['third_party/libvpx/source/libvpx/LICENSE'], 42
33 'libyuv': ['third_party/libyuv/LICENSE'], 43 # Compile time dependencies, no license needed:
44 'yasm': [],
34 } 45 }
35 46
36 SCRIPT_DIR = os.path.dirname(os.path.realpath(sys.argv[0])) 47 SCRIPT_DIR = os.path.dirname(os.path.realpath(sys.argv[0]))
37 CHECKOUT_ROOT = os.path.abspath(os.path.join(SCRIPT_DIR, os.pardir, os.pardir)) 48 CHECKOUT_ROOT = os.path.abspath(os.path.join(SCRIPT_DIR, os.pardir, os.pardir))
38 WEBRTC_ROOT = os.path.join(CHECKOUT_ROOT, 'webrtc') 49 WEBRTC_ROOT = os.path.join(CHECKOUT_ROOT, 'webrtc')
50 THIRD_PARTY_LIB_REGEX = r'^.*/third_party/([\w+]+).*$'
39 51
52 def GetThirdPartyLibraries(buildfile_dir, target):
53 def ParseLibrary(dep):
54 """
55 Returns a regex match containing library name after third_party
40 56
41 def GetThirdPartyLibraries(buildfile_dir, target_name): 57 Input one of:
42 def ExtractLibName(string_list): 58 //a/b/third_party/libname:c
43 # Sample input: 59 //a/b/third_party/libname:c(d)
44 # [" //third_party/usrsctp:usrsctp", " //webrtc:webrtc_common"] 60 //a/b/third_party/libname/c:d(e)
45 # Sample output: 61
46 # ["usrsctp"] 62 Outputs match with libname in group 1 or None if this is not a third_party
47 return re.sub(r'\(.*\)', '', string_list).strip().split( 63 dependency.
48 os.path.sep)[-1].split(':')[0] 64 """
49 output = subprocess.check_output( 65 return re.match(THIRD_PARTY_LIB_REGEX, dep)
50 ["gn", "desc", buildfile_dir, target_name, '--all']) .split(os.linesep) 66
51 return [ExtractLibName(x) for x in output if re.search(r'third_party', x)] 67 cmd = ["gn", "desc", '--all', '--format=json', os.path.abspath(buildfile_dir),
68 target]
69 logging.debug("Running: %r", cmd)
70 output_json = subprocess.check_output(cmd)
71 logging.debug("Output: %s", output_json)
72 output = json.loads(output_json)
73
74 libraries = set()
75 for target in output.values():
76 third_party_matches = (ParseLibrary(dep) for dep in target['deps'])
77 libraries |= set(match.group(1) for match in third_party_matches if match)
78 return libraries
52 79
53 80
54 class LicenseBuilder(object): 81 class LicenseBuilder(object):
55 82
56 def __init__(self, buildfile_dirs, target_name): 83 def __init__(self, buildfile_dirs, targets):
57 self.buildfile_dirs = buildfile_dirs 84 self.buildfile_dirs = buildfile_dirs
58 self.target_name = target_name 85 self.targets = targets
59 86
60 def GenerateLicenseText(self, output_dir): 87 def GenerateLicenseText(self, output_dir):
61 # Get a list of third_party libs from gn. For fat libraries we must consider 88 # Get a list of third_party libs from gn. For fat libraries we must consider
62 # all architectures, hence the multiple buildfile directories. 89 # all architectures, hence the multiple buildfile directories.
63 # The `sum` function flattens the 2d list. 90 third_party_libs = set()
64 third_party_libs = sum([GetThirdPartyLibraries(buildfile, self.target_name) 91 for buildfile in self.buildfile_dirs:
65 for buildfile in self.buildfile_dirs], []) 92 for target in self.targets:
93 third_party_libs |= GetThirdPartyLibraries(buildfile, target)
66 assert len(third_party_libs) > 0 94 assert len(third_party_libs) > 0
67 95
68 # Generate amalgamated list of libraries. Will exit with error if a 96 missing_licenses = third_party_libs - set(LIB_TO_LICENSES_DICT.keys())
69 # lib is unrecognized. 97 if missing_licenses:
kjellander_webrtc 2017/09/01 08:44:52 What does this mean? Doesn't it mean that it will
sakal 2017/09/01 11:02:30 This exception is thrown if there are deps found i
70 license_libs = set() 98 error_msg = 'Missing licenses: %s' % ', '.join(missing_licenses)
71 for static_lib in third_party_libs: 99 logging.error(error_msg)
72 license_path = LIB_TO_LICENSES_DICT.get(static_lib) 100 raise Exception(error_msg)
73 if static_lib == 'yasm':
74 # yasm is a build-time dep only, and doesn't need a license.
75 continue
76 if license_path is None:
77 print 'Missing license path for lib: %s' % static_lib
78 return 1
79 license_libs.add(static_lib)
80 101
81 # Put webrtc at the front of the list. 102 # Put webrtc at the front of the list.
82 license_libs = sorted(license_libs) 103 license_libs = sorted(third_party_libs)
83 license_libs.insert(0, 'webrtc') 104 license_libs.insert(0, 'webrtc')
84 105
85 # Generate HTML. 106 logging.info("List of licenses: %s", ', '.join(license_libs))
86 output_license_file = open(os.path.join(output_dir, 'LICENSE.html'), 'w+')
87 output_license_file.write('<!DOCTYPE html>\n')
88 output_license_file.write('<html>\n<head>\n')
89 output_license_file.write('<meta charset="UTF-8">\n')
90 output_license_file.write('<title>Licenses</title>\n')
91 style_tag = textwrap.dedent('''\
92 <style>
93 body { margin: 0; font-family: sans-serif; }
94 pre { background-color: #eeeeee; padding: 1em; white-space: pre-wrap; }
95 p { margin: 1em; white-space: nowrap; }
96 </style>
97 ''')
98 output_license_file.write(style_tag)
99 output_license_file.write('</head>\n')
100 107
108 # Generate markdown.
109 output_license_file = open(os.path.join(output_dir, 'LICENSE.md'), 'w+')
101 for license_lib in license_libs: 110 for license_lib in license_libs:
102 output_license_file.write('<p>%s<br/></p>\n' % license_lib) 111 if len(LIB_TO_LICENSES_DICT[license_lib]) == 0:
103 output_license_file.write('<pre>\n') 112 logging.info("Skipping compile time dependency: %s", license_lib)
113 continue # Compile time dependency
114
115 output_license_file.write('# %s\n' % license_lib)
116 output_license_file.write('```\n')
104 for path in LIB_TO_LICENSES_DICT[license_lib]: 117 for path in LIB_TO_LICENSES_DICT[license_lib]:
105 license_path = os.path.join(CHECKOUT_ROOT, path) 118 license_path = os.path.join(CHECKOUT_ROOT, path)
106 with open(license_path, 'r') as license_file: 119 with open(license_path, 'r') as license_file:
107 license_text = cgi.escape(license_file.read(), quote=True) 120 license_text = cgi.escape(license_file.read(), quote=True)
108 output_license_file.write(license_text) 121 output_license_file.write(license_text)
109 output_license_file.write('\n') 122 output_license_file.write('\n')
110 output_license_file.write('</pre>\n') 123 output_license_file.write('```\n\n')
111 124
112 output_license_file.write('</body>\n')
113 output_license_file.write('</html>')
114 output_license_file.close() 125 output_license_file.close()
115 return 0
116 126
117 127
118 def main(): 128 def main():
119 parser = argparse.ArgumentParser(description='Generate WebRTC LICENSE.html') 129 parser = argparse.ArgumentParser(description='Generate WebRTC LICENSE.md')
120 parser.add_argument('target_name', 130 parser.add_argument('--verbose', action='store_true', default=False,
131 help='Debug logging.')
132 parser.add_argument('--target', required=True, action='append', default=[],
121 help='Name of the GN target to generate a license for') 133 help='Name of the GN target to generate a license for')
122 parser.add_argument('output_dir', 134 parser.add_argument('output_dir',
123 help='Directory to output LICENSE.html to.') 135 help='Directory to output LICENSE.md to.')
124 parser.add_argument('buildfile_dirs', nargs="+", 136 parser.add_argument('buildfile_dirs', nargs="+",
125 help='Directories containing gn generated ninja files') 137 help='Directories containing gn generated ninja files')
126 args = parser.parse_args() 138 args = parser.parse_args()
127 builder = LicenseBuilder(args.buildfile_dirs, args.target_name) 139
128 sys.exit(builder.GenerateLicenseText(args.output_dir)) 140 logging.basicConfig(level=logging.DEBUG if args.verbose else logging.INFO)
141
142 builder = LicenseBuilder(args.buildfile_dirs, args.target)
143 builder.GenerateLicenseText(args.output_dir)
129 144
130 145
131 if __name__ == '__main__': 146 if __name__ == '__main__':
132 main() 147 sys.exit(main())
OLDNEW
« tools_webrtc/android/build_aar.py ('K') | « tools_webrtc/libs/__init__.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698