Chromium Code Reviews| Index: tools/licenses.py |
| diff --git a/tools/licenses.py b/tools/licenses.py |
| index 17dc94a3aab165e29e891a19b42189909aec5750..ac97d21f0ccd4bd29a9f4d66edd3f9163b9eb347 100755 |
| --- a/tools/licenses.py |
| +++ b/tools/licenses.py |
| @@ -18,8 +18,10 @@ Commands: |
| import argparse |
| import cgi |
| import os |
| +import shutil |
| import subprocess |
| import sys |
| +import tempfile |
| # TODO(agrieve): Move build_utils.WriteDepFile into a non-android directory. |
| _REPOSITORY_ROOT = os.path.dirname(os.path.dirname(__file__)) |
| @@ -482,9 +484,22 @@ def FindThirdPartyDeps(gn_out_dir, gn_target): |
| if not gn_out_dir: |
| raise RuntimeError("--gn-out-dir is required if --gn-target is used.") |
| - gn_deps = subprocess.check_output([_GnBinary(), "desc", gn_out_dir, |
| - gn_target, |
| - "deps", "--as=buildfile", "--all"]) |
| + # Generate gn project in temp directory and use it to find dependencies. |
| + # Current gn directory cannot be used when we run this script in a gn action |
| + # rule, because gn doesn't allow recursive invocations due to potential side |
| + # effects. |
| + tmp_dir = None |
| + try: |
| + tmp_dir = tempfile.mkdtemp(dir = gn_out_dir) |
| + shutil.copy(gn_out_dir + "/args.gn", tmp_dir) |
|
Paweł Hajdan Jr.
2017/04/06 11:52:13
nit: Use os.path.join instead of "+".
Hiroshi Ichikawa
2017/04/07 01:47:16
Done.
|
| + subprocess.check_output([_GnBinary(), "gen", tmp_dir]) |
| + gn_deps = subprocess.check_output([ |
| + _GnBinary(), "desc", tmp_dir, gn_target, |
| + "deps", "--as=buildfile", "--all"]) |
| + finally: |
| + if tmp_dir and os.path.exists(tmp_dir): |
| + shutil.rmtree(tmp_dir) |
| + |
| third_party_deps = set() |
| for build_dep in gn_deps.split(): |
| if ("third_party" in build_dep and |
| @@ -606,6 +621,53 @@ def GenerateCredits( |
| return True |
| +def _ReadFile(path): |
| + """Reads a file from disk. |
| + Args: |
| + path: The path of the file to read, relative to the root of the |
| + repository. |
| + Returns: |
| + The contents of the file as a string. |
| + """ |
| + with open(os.path.join(_REPOSITORY_ROOT, path), 'rb') as f: |
| + return f.read() |
| + |
| + |
| +def GenerateLicenseFile(output_file, gn_out_dir, gn_target): |
| + """Generate a plain-text LICENSE file which can be used when you ship a part |
| + of Chromium code (specified by gn_target) as a stand-alone library |
| + (e.g., //ios/web_view). |
| + |
| + The LICENSE file contains licenses of both Chromium and third-party |
| + libraries which gn_target depends on. """ |
| + |
| + third_party_dirs = FindThirdPartyDeps(gn_out_dir, gn_target) |
| + |
| + # Start with Chromium's LICENSE file. |
| + content = [_ReadFile('LICENSE')] |
| + |
| + # Add necessary third_party. |
| + for directory in sorted(third_party_dirs): |
| + metadata = ParseDir( |
| + directory, _REPOSITORY_ROOT, require_license_file=True) |
| + content.append('-' * 20) |
| + content.append(directory.split("/")[-1]) |
|
Paweł Hajdan Jr.
2017/04/06 11:52:13
nit: Use single quotes ' .
Hiroshi Ichikawa
2017/04/07 01:47:16
Done.
|
| + content.append('-' * 20) |
| + license_file = metadata['License File'] |
| + if license_file and license_file != NOT_SHIPPED: |
| + content.append(_ReadFile(license_file)) |
| + |
| + content_text = '\n'.join(content) |
| + |
| + if output_file: |
| + with open(output_file, 'w') as output: |
| + output.write(content_text) |
| + else: |
| + print content_text |
| + |
| + return True |
| + |
| + |
| def main(): |
| parser = argparse.ArgumentParser() |
| parser.add_argument('--file-template', |
| @@ -618,7 +680,8 @@ def main(): |
| help='GN output directory for scanning dependencies.') |
| parser.add_argument('--gn-target', |
| help='GN target to scan for dependencies.') |
| - parser.add_argument('command', choices=['help', 'scan', 'credits']) |
| + parser.add_argument('command', |
| + choices=['help', 'scan', 'credits', 'license_file']) |
| parser.add_argument('output_file', nargs='?') |
| build_utils.AddDepfileOption(parser) |
| args = parser.parse_args() |
| @@ -631,6 +694,10 @@ def main(): |
| args.output_file, args.target_os, |
| args.gn_out_dir, args.gn_target, args.depfile): |
| return 1 |
| + elif args.command == 'license_file': |
| + if not GenerateLicenseFile( |
| + args.output_file, args.gn_out_dir, args.gn_target): |
| + return 1 |
| else: |
| print __doc__ |
| return 1 |