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

Side by Side Diff: tools/licenses.py

Issue 2670833004: Use a depfile to know when to regenerate notice files (Closed)
Patch Set: Created 3 years, 10 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/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 sys 21 import sys
22 22
23 # TODO(agrieve): Move build_utils.WriteDepFile into a non-android directory.
24 _REPOSITORY_ROOT = os.path.dirname(os.path.dirname(__file__))
25 sys.path.append(os.path.join(_REPOSITORY_ROOT, 'build/android/gyp/util'))
26 import build_utils
27
28
23 # Paths from the root of the tree to directories to skip. 29 # Paths from the root of the tree to directories to skip.
24 PRUNE_PATHS = set([ 30 PRUNE_PATHS = set([
25 # Placeholder directory only, not third-party code. 31 # Placeholder directory only, not third-party code.
26 os.path.join('third_party','adobe'), 32 os.path.join('third_party','adobe'),
27 33
28 # Already covered by //third_party/android_tools. 34 # Already covered by //third_party/android_tools.
29 os.path.join('third_party','android_tools_internal'), 35 os.path.join('third_party','android_tools_internal'),
30 36
31 # Apache 2.0 license. See crbug.com/140478 37 # Apache 2.0 license. See crbug.com/140478
32 os.path.join('third_party','bidichecker'), 38 os.path.join('third_party','bidichecker'),
(...skipping 436 matching lines...) Expand 10 before | Expand all | Expand 10 after
469 errors.append((path, e.args[0])) 475 errors.append((path, e.args[0]))
470 continue 476 continue
471 477
472 for path, error in sorted(errors): 478 for path, error in sorted(errors):
473 print path + ": " + error 479 print path + ": " + error
474 480
475 return len(errors) == 0 481 return len(errors) == 0
476 482
477 483
478 def GenerateCredits( 484 def GenerateCredits(
479 file_template_file, entry_template_file, output_file, target_os): 485 file_template_file, entry_template_file, output_file, target_os,
486 depfile=None):
480 """Generate about:credits.""" 487 """Generate about:credits."""
481 488
482 def EvaluateTemplate(template, env, escape=True): 489 def EvaluateTemplate(template, env, escape=True):
483 """Expand a template with variables like {{foo}} using a 490 """Expand a template with variables like {{foo}} using a
484 dictionary of expansions.""" 491 dictionary of expansions."""
485 for key, val in env.items(): 492 for key, val in env.items():
486 if escape: 493 if escape:
487 val = cgi.escape(val) 494 val = cgi.escape(val)
488 template = template.replace('{{%s}}' % key, val) 495 template = template.replace('{{%s}}' % key, val)
489 return template 496 return template
490 497
491 root = os.path.join(os.path.dirname(__file__), '..') 498 third_party_dirs = FindThirdPartyDirs(PRUNE_PATHS, _REPOSITORY_ROOT)
492 third_party_dirs = FindThirdPartyDirs(PRUNE_PATHS, root)
493 499
494 if not file_template_file: 500 if not file_template_file:
495 file_template_file = os.path.join(root, 'components', 'about_ui', 501 file_template_file = os.path.join(_REPOSITORY_ROOT, 'components',
496 'resources', 'about_credits.tmpl') 502 'about_ui', 'resources',
503 'about_credits.tmpl')
497 if not entry_template_file: 504 if not entry_template_file:
498 entry_template_file = os.path.join(root, 'components', 'about_ui', 505 entry_template_file = os.path.join(_REPOSITORY_ROOT, 'components',
499 'resources', 506 'about_ui', 'resources',
500 'about_credits_entry.tmpl') 507 'about_credits_entry.tmpl')
501 508
502 entry_template = open(entry_template_file).read() 509 entry_template = open(entry_template_file).read()
503 entries = [] 510 entries = []
504 for path in third_party_dirs: 511 for path in third_party_dirs:
505 try: 512 try:
506 metadata = ParseDir(path, root) 513 metadata = ParseDir(path, _REPOSITORY_ROOT)
507 except LicenseError: 514 except LicenseError:
508 # TODO(phajdan.jr): Convert to fatal error (http://crbug.com/39240). 515 # TODO(phajdan.jr): Convert to fatal error (http://crbug.com/39240).
509 continue 516 continue
510 if metadata['License File'] == NOT_SHIPPED: 517 if metadata['License File'] == NOT_SHIPPED:
511 continue 518 continue
512 if target_os == 'ios': 519 if target_os == 'ios':
513 # Skip over files that are known not to be used on iOS. 520 # Skip over files that are known not to be used on iOS.
514 if path in KNOWN_NON_IOS_LIBRARIES: 521 if path in KNOWN_NON_IOS_LIBRARIES:
515 continue 522 continue
516 env = { 523 env = {
517 'name': metadata['Name'], 524 'name': metadata['Name'],
518 'url': metadata['URL'], 525 'url': metadata['URL'],
519 'license': open(metadata['License File'], 'rb').read(), 526 'license': open(metadata['License File'], 'rb').read(),
520 } 527 }
521 entry = { 528 entry = {
522 'name': metadata['Name'], 529 'name': metadata['Name'],
523 'content': EvaluateTemplate(entry_template, env), 530 'content': EvaluateTemplate(entry_template, env),
531 'license_file': metadata['License File'],
524 } 532 }
525 entries.append(entry) 533 entries.append(entry)
526 534
527 entries.sort(key=lambda entry: (entry['name'], entry['content'])) 535 entries.sort(key=lambda entry: (entry['name'], entry['content']))
528 entries_contents = '\n'.join([entry['content'] for entry in entries]) 536 entries_contents = '\n'.join([entry['content'] for entry in entries])
529 file_template = open(file_template_file).read() 537 file_template = open(file_template_file).read()
530 template_contents = "<!-- Generated by licenses.py; do not edit. -->" 538 template_contents = "<!-- Generated by licenses.py; do not edit. -->"
531 template_contents += EvaluateTemplate(file_template, 539 template_contents += EvaluateTemplate(file_template,
532 {'entries': entries_contents}, 540 {'entries': entries_contents},
533 escape=False) 541 escape=False)
534 542
535 if output_file: 543 if output_file:
536 with open(output_file, 'w') as output: 544 with open(output_file, 'w') as output:
537 output.write(template_contents) 545 output.write(template_contents)
538 else: 546 else:
539 print template_contents 547 print template_contents
540 548
549 if depfile:
550 assert output_file
551 # Add in build.ninja so that the target will be considered dirty whenever
552 # gn gen is run. Otherwise, it will fail to notice new files being added.
553 # This is still no perfect, as it will fail if no build files are changed,
554 # but a new README.chromium / LICENSE is added. This shouldn't happen in
555 # practice however.
556 license_file_list = (entry['license_file'] for entry in entries)
557 license_file_list = (os.path.relpath(p) for p in license_file_list)
558 license_file_list = sorted(set(license_file_list))
559 build_utils.WriteDepfile(depfile, output_file,
560 license_file_list + ['build.ninja'])
561
541 return True 562 return True
542 563
543 564
544 def main(): 565 def main():
545 parser = argparse.ArgumentParser() 566 parser = argparse.ArgumentParser()
546 parser.add_argument('--file-template', 567 parser.add_argument('--file-template',
547 help='Template HTML to use for the license page.') 568 help='Template HTML to use for the license page.')
548 parser.add_argument('--entry-template', 569 parser.add_argument('--entry-template',
549 help='Template HTML to use for each license.') 570 help='Template HTML to use for each license.')
550 parser.add_argument('--target-os', 571 parser.add_argument('--target-os',
551 help='OS that this build is targeting.') 572 help='OS that this build is targeting.')
552 parser.add_argument('command', choices=['help', 'scan', 'credits']) 573 parser.add_argument('command', choices=['help', 'scan', 'credits'])
553 parser.add_argument('output_file', nargs='?') 574 parser.add_argument('output_file', nargs='?')
575 build_utils.AddDepfileOption(parser)
554 args = parser.parse_args() 576 args = parser.parse_args()
555 577
556 if args.command == 'scan': 578 if args.command == 'scan':
557 if not ScanThirdPartyDirs(): 579 if not ScanThirdPartyDirs():
558 return 1 580 return 1
559 elif args.command == 'credits': 581 elif args.command == 'credits':
560 if not GenerateCredits(args.file_template, args.entry_template, 582 if not GenerateCredits(args.file_template, args.entry_template,
561 args.output_file, args.target_os): 583 args.output_file, args.target_os, args.depfile):
562 return 1 584 return 1
563 else: 585 else:
564 print __doc__ 586 print __doc__
565 return 1 587 return 1
566 588
567 589
568 if __name__ == '__main__': 590 if __name__ == '__main__':
569 sys.exit(main()) 591 sys.exit(main())
OLDNEW
« android_webview/tools/webview_licenses.py ('K') | « remoting/webapp/BUILD.gn ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698