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

Side by Side Diff: tools/licenses.py

Issue 2797403002: Merge features of cronet_licenses.py into licenses.py. (Closed)
Patch Set: Apply review comments. Created 3 years, 8 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 5
6 """Utility for checking and processing licensing information in third_party 6 """Utility for checking and processing licensing information in third_party
7 directories. 7 directories.
8 8
9 Usage: licenses.py <command> 9 Usage: licenses.py <command>
10 10
11 Commands: 11 Commands:
12 scan scan third_party directories, verifying that we have licensing info 12 scan scan third_party directories, verifying that we have licensing info
13 credits generate about:credits on stdout 13 credits generate about:credits on stdout
14 14
15 (You can also import this as a module.) 15 (You can also import this as a module.)
16 """ 16 """
17 17
18 import argparse 18 import argparse
19 import cgi 19 import cgi
20 import os 20 import os
21 import shutil
21 import subprocess 22 import subprocess
22 import sys 23 import sys
24 import tempfile
23 25
24 # TODO(agrieve): Move build_utils.WriteDepFile into a non-android directory. 26 # TODO(agrieve): Move build_utils.WriteDepFile into a non-android directory.
25 _REPOSITORY_ROOT = os.path.dirname(os.path.dirname(__file__)) 27 _REPOSITORY_ROOT = os.path.dirname(os.path.dirname(__file__))
26 sys.path.append(os.path.join(_REPOSITORY_ROOT, 'build/android/gyp/util')) 28 sys.path.append(os.path.join(_REPOSITORY_ROOT, 'build/android/gyp/util'))
27 import build_utils 29 import build_utils
28 30
29 31
30 # Paths from the root of the tree to directories to skip. 32 # Paths from the root of the tree to directories to skip.
31 PRUNE_PATHS = set([ 33 PRUNE_PATHS = set([
32 # Placeholder directory only, not third-party code. 34 # Placeholder directory only, not third-party code.
(...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after
475 else: 477 else:
476 raise RuntimeError("Unsupported platform '%s'." % sys.platform) 478 raise RuntimeError("Unsupported platform '%s'." % sys.platform)
477 479
478 return os.path.join(_REPOSITORY_ROOT, 'buildtools', subdir, exe) 480 return os.path.join(_REPOSITORY_ROOT, 'buildtools', subdir, exe)
479 481
480 482
481 def FindThirdPartyDeps(gn_out_dir, gn_target): 483 def FindThirdPartyDeps(gn_out_dir, gn_target):
482 if not gn_out_dir: 484 if not gn_out_dir:
483 raise RuntimeError("--gn-out-dir is required if --gn-target is used.") 485 raise RuntimeError("--gn-out-dir is required if --gn-target is used.")
484 486
485 gn_deps = subprocess.check_output([_GnBinary(), "desc", gn_out_dir, 487 # Generate gn project in temp directory and use it to find dependencies.
486 gn_target, 488 # Current gn directory cannot be used when we run this script in a gn action
487 "deps", "--as=buildfile", "--all"]) 489 # rule, because gn doesn't allow recursive invocations due to potential side
490 # effects.
491 tmp_dir = None
492 try:
493 tmp_dir = tempfile.mkdtemp(dir = gn_out_dir)
494 shutil.copy(os.path.join(gn_out_dir, "args.gn"), tmp_dir)
495 subprocess.check_output([_GnBinary(), "gen", tmp_dir])
496 gn_deps = subprocess.check_output([
497 _GnBinary(), "desc", tmp_dir, gn_target,
498 "deps", "--as=buildfile", "--all"])
499 finally:
500 if tmp_dir and os.path.exists(tmp_dir):
501 shutil.rmtree(tmp_dir)
502
488 third_party_deps = set() 503 third_party_deps = set()
489 for build_dep in gn_deps.split(): 504 for build_dep in gn_deps.split():
490 if ("third_party" in build_dep and 505 if ("third_party" in build_dep and
491 os.path.basename(build_dep) == "BUILD.gn"): 506 os.path.basename(build_dep) == "BUILD.gn"):
492 third_party_deps.add(os.path.dirname(build_dep)) 507 third_party_deps.add(os.path.dirname(build_dep))
493 return third_party_deps 508 return third_party_deps
494 509
495 510
496 def ScanThirdPartyDirs(root=None): 511 def ScanThirdPartyDirs(root=None):
497 """Scan a list of directories and report on any problems we find.""" 512 """Scan a list of directories and report on any problems we find."""
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
607 # practice however. 622 # practice however.
608 license_file_list = (entry['license_file'] for entry in entries) 623 license_file_list = (entry['license_file'] for entry in entries)
609 license_file_list = (os.path.relpath(p) for p in license_file_list) 624 license_file_list = (os.path.relpath(p) for p in license_file_list)
610 license_file_list = sorted(set(license_file_list)) 625 license_file_list = sorted(set(license_file_list))
611 build_utils.WriteDepfile(depfile, output_file, 626 build_utils.WriteDepfile(depfile, output_file,
612 license_file_list + ['build.ninja']) 627 license_file_list + ['build.ninja'])
613 628
614 return True 629 return True
615 630
616 631
632 def _ReadFile(path):
633 """Reads a file from disk.
634 Args:
635 path: The path of the file to read, relative to the root of the
636 repository.
637 Returns:
638 The contents of the file as a string.
639 """
640 with open(os.path.join(_REPOSITORY_ROOT, path), 'rb') as f:
641 return f.read()
642
643
644 def GenerateLicenseFile(output_file, gn_out_dir, gn_target):
645 """Generate a plain-text LICENSE file which can be used when you ship a part
646 of Chromium code (specified by gn_target) as a stand-alone library
647 (e.g., //ios/web_view).
648
649 The LICENSE file contains licenses of both Chromium and third-party
650 libraries which gn_target depends on. """
651
652 third_party_dirs = FindThirdPartyDeps(gn_out_dir, gn_target)
653
654 # Start with Chromium's LICENSE file.
655 content = [_ReadFile('LICENSE')]
656
657 # Add necessary third_party.
658 for directory in sorted(third_party_dirs):
659 metadata = ParseDir(
660 directory, _REPOSITORY_ROOT, require_license_file=True)
661 content.append('-' * 20)
662 content.append(directory.split('/')[-1])
663 content.append('-' * 20)
664 license_file = metadata['License File']
665 if license_file and license_file != NOT_SHIPPED:
666 content.append(_ReadFile(license_file))
667
668 content_text = '\n'.join(content)
669
670 if output_file:
671 with open(output_file, 'w') as output:
672 output.write(content_text)
673 else:
674 print content_text
675
676 return True
677
678
617 def main(): 679 def main():
618 parser = argparse.ArgumentParser() 680 parser = argparse.ArgumentParser()
619 parser.add_argument('--file-template', 681 parser.add_argument('--file-template',
620 help='Template HTML to use for the license page.') 682 help='Template HTML to use for the license page.')
621 parser.add_argument('--entry-template', 683 parser.add_argument('--entry-template',
622 help='Template HTML to use for each license.') 684 help='Template HTML to use for each license.')
623 parser.add_argument('--target-os', 685 parser.add_argument('--target-os',
624 help='OS that this build is targeting.') 686 help='OS that this build is targeting.')
625 parser.add_argument('--gn-out-dir', 687 parser.add_argument('--gn-out-dir',
626 help='GN output directory for scanning dependencies.') 688 help='GN output directory for scanning dependencies.')
627 parser.add_argument('--gn-target', 689 parser.add_argument('--gn-target',
628 help='GN target to scan for dependencies.') 690 help='GN target to scan for dependencies.')
629 parser.add_argument('command', choices=['help', 'scan', 'credits']) 691 parser.add_argument('command',
692 choices=['help', 'scan', 'credits', 'license_file'])
630 parser.add_argument('output_file', nargs='?') 693 parser.add_argument('output_file', nargs='?')
631 build_utils.AddDepfileOption(parser) 694 build_utils.AddDepfileOption(parser)
632 args = parser.parse_args() 695 args = parser.parse_args()
633 696
634 if args.command == 'scan': 697 if args.command == 'scan':
635 if not ScanThirdPartyDirs(): 698 if not ScanThirdPartyDirs():
636 return 1 699 return 1
637 elif args.command == 'credits': 700 elif args.command == 'credits':
638 if not GenerateCredits(args.file_template, args.entry_template, 701 if not GenerateCredits(args.file_template, args.entry_template,
639 args.output_file, args.target_os, 702 args.output_file, args.target_os,
640 args.gn_out_dir, args.gn_target, args.depfile): 703 args.gn_out_dir, args.gn_target, args.depfile):
641 return 1 704 return 1
705 elif args.command == 'license_file':
706 if not GenerateLicenseFile(
707 args.output_file, args.gn_out_dir, args.gn_target):
708 return 1
642 else: 709 else:
643 print __doc__ 710 print __doc__
644 return 1 711 return 1
645 712
646 713
647 if __name__ == '__main__': 714 if __name__ == '__main__':
648 sys.exit(main()) 715 sys.exit(main())
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698