OLD | NEW |
---|---|
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 """Makes sure that all files contain proper licensing information.""" | 6 """Makes sure that all files contain proper licensing information.""" |
7 | 7 |
8 | 8 |
9 import fnmatch | |
Paweł Hajdan Jr.
2015/04/02 09:58:24
PLease do not add fnmatch support to checklicenses
| |
9 import json | 10 import json |
10 import optparse | 11 import optparse |
11 import os.path | 12 import os.path |
12 import subprocess | 13 import subprocess |
13 import sys | 14 import sys |
14 | 15 |
15 | 16 |
16 def PrintUsage(): | 17 def PrintUsage(): |
17 print """Usage: python checklicenses.py [--root <root>] [tocheck] | 18 print """Usage: python checklicenses.py [--root <root>] [tocheck] |
18 --root Specifies the repository root. This defaults to "../.." relative | 19 --root Specifies the repository root. This defaults to "../.." relative |
(...skipping 395 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
414 ], | 415 ], |
415 'v8/test/cctest': [ # http://crbug.com/98597 | 416 'v8/test/cctest': [ # http://crbug.com/98597 |
416 'UNKNOWN', | 417 'UNKNOWN', |
417 ], | 418 ], |
418 'v8/src/third_party/kernel/tools/perf/util/jitdump.h': [ # http://crbug.com /391716 | 419 'v8/src/third_party/kernel/tools/perf/util/jitdump.h': [ # http://crbug.com /391716 |
419 'UNKNOWN', | 420 'UNKNOWN', |
420 ], | 421 ], |
421 } | 422 } |
422 | 423 |
423 | 424 |
425 FNMATCH_WHITELISTED_LICENSES = { | |
426 'third_party/jsoncpp/source/*.py': [ # http://crbug.com/472816 | |
427 'UNKNOWN', | |
428 ], | |
429 } | |
430 | |
431 | |
424 def check_licenses(options, args): | 432 def check_licenses(options, args): |
425 # Figure out which directory we have to check. | 433 # Figure out which directory we have to check. |
426 if len(args) == 0: | 434 if len(args) == 0: |
427 # No directory to check specified, use the repository root. | 435 # No directory to check specified, use the repository root. |
428 start_dir = options.base_directory | 436 start_dir = options.base_directory |
429 elif len(args) == 1: | 437 elif len(args) == 1: |
430 # Directory specified. Start here. It's supposed to be relative to the | 438 # Directory specified. Start here. It's supposed to be relative to the |
431 # base directory. | 439 # base directory. |
432 start_dir = os.path.abspath(os.path.join(options.base_directory, args[0])) | 440 start_dir = os.path.abspath(os.path.join(options.base_directory, args[0])) |
433 else: | 441 else: |
(...skipping 21 matching lines...) Expand all Loading... | |
455 print stdout | 463 print stdout |
456 print '--------- end licensecheck stdout ---------' | 464 print '--------- end licensecheck stdout ---------' |
457 if licensecheck.returncode != 0 or stderr: | 465 if licensecheck.returncode != 0 or stderr: |
458 print '----------- licensecheck stderr -----------' | 466 print '----------- licensecheck stderr -----------' |
459 print stderr | 467 print stderr |
460 print '--------- end licensecheck stderr ---------' | 468 print '--------- end licensecheck stderr ---------' |
461 print "\nFAILED\n" | 469 print "\nFAILED\n" |
462 return 1 | 470 return 1 |
463 | 471 |
464 used_suppressions = set() | 472 used_suppressions = set() |
473 used_fnmatch_suppressions = set() | |
465 errors = [] | 474 errors = [] |
466 | 475 |
467 for line in stdout.splitlines(): | 476 for line in stdout.splitlines(): |
468 filename, license = line.split(':', 1) | 477 filename, license = line.split(':', 1) |
469 filename = os.path.relpath(filename.strip(), options.base_directory) | 478 filename = os.path.relpath(filename.strip(), options.base_directory) |
470 | 479 |
471 # All files in the build output directory are generated one way or another. | 480 # All files in the build output directory are generated one way or another. |
472 # There's no need to check them. | 481 # There's no need to check them. |
473 if filename.startswith('out/'): | 482 if filename.startswith('out/'): |
474 continue | 483 continue |
(...skipping 10 matching lines...) Expand all Loading... | |
485 | 494 |
486 if not options.ignore_suppressions: | 495 if not options.ignore_suppressions: |
487 matched_prefixes = [ | 496 matched_prefixes = [ |
488 prefix for prefix in PATH_SPECIFIC_WHITELISTED_LICENSES | 497 prefix for prefix in PATH_SPECIFIC_WHITELISTED_LICENSES |
489 if filename.startswith(prefix) and | 498 if filename.startswith(prefix) and |
490 license in PATH_SPECIFIC_WHITELISTED_LICENSES[prefix]] | 499 license in PATH_SPECIFIC_WHITELISTED_LICENSES[prefix]] |
491 if matched_prefixes: | 500 if matched_prefixes: |
492 used_suppressions.update(set(matched_prefixes)) | 501 used_suppressions.update(set(matched_prefixes)) |
493 continue | 502 continue |
494 | 503 |
504 matched_pattern = None | |
505 for pattern in FNMATCH_WHITELISTED_LICENSES: | |
506 if fnmatch.fnmatch(filename, pattern): | |
507 matched_pattern = pattern | |
508 break | |
509 | |
510 if matched_pattern: | |
511 used_fnmatch_suppressions.add(matched_pattern) | |
512 continue | |
513 | |
495 errors.append({'filename': filename, 'license': license}) | 514 errors.append({'filename': filename, 'license': license}) |
496 | 515 |
497 if options.json: | 516 if options.json: |
498 with open(options.json, 'w') as f: | 517 with open(options.json, 'w') as f: |
499 json.dump(errors, f) | 518 json.dump(errors, f) |
500 | 519 |
501 if errors: | 520 if errors: |
502 for error in errors: | 521 for error in errors: |
503 print "'%s' has non-whitelisted license '%s'" % ( | 522 print "'%s' has non-whitelisted license '%s'" % ( |
504 error['filename'], error['license']) | 523 error['filename'], error['license']) |
(...skipping 14 matching lines...) Expand all Loading... | |
519 print "\nSUCCESS\n" | 538 print "\nSUCCESS\n" |
520 | 539 |
521 if not len(args): | 540 if not len(args): |
522 unused_suppressions = set( | 541 unused_suppressions = set( |
523 PATH_SPECIFIC_WHITELISTED_LICENSES.iterkeys()).difference( | 542 PATH_SPECIFIC_WHITELISTED_LICENSES.iterkeys()).difference( |
524 used_suppressions) | 543 used_suppressions) |
525 if unused_suppressions: | 544 if unused_suppressions: |
526 print "\nNOTE: unused suppressions detected:\n" | 545 print "\nNOTE: unused suppressions detected:\n" |
527 print '\n'.join(unused_suppressions) | 546 print '\n'.join(unused_suppressions) |
528 | 547 |
548 unused_fnmatch_suppressions = set( | |
549 FNMATCH_WHITELISTED_LICENSES.iterkeys()).difference( | |
550 used_fnmatch_suppressions) | |
551 if unused_fnmatch_suppressions: | |
552 print "\nNOTE: unused fnmatch suppressions detected:\n" | |
553 print '\n'.join(unused_fnmatch_suppressions) | |
554 | |
529 return 0 | 555 return 0 |
530 | 556 |
531 | 557 |
532 def main(): | 558 def main(): |
533 default_root = os.path.abspath( | 559 default_root = os.path.abspath( |
534 os.path.join(os.path.dirname(__file__), '..', '..')) | 560 os.path.join(os.path.dirname(__file__), '..', '..')) |
535 option_parser = optparse.OptionParser() | 561 option_parser = optparse.OptionParser() |
536 option_parser.add_option('--root', default=default_root, | 562 option_parser.add_option('--root', default=default_root, |
537 dest='base_directory', | 563 dest='base_directory', |
538 help='Specifies the repository root. This defaults ' | 564 help='Specifies the repository root. This defaults ' |
539 'to "../.." relative to the script file, which ' | 565 'to "../.." relative to the script file, which ' |
540 'will normally be the repository root.') | 566 'will normally be the repository root.') |
541 option_parser.add_option('-v', '--verbose', action='store_true', | 567 option_parser.add_option('-v', '--verbose', action='store_true', |
542 default=False, help='Print debug logging') | 568 default=False, help='Print debug logging') |
543 option_parser.add_option('--ignore-suppressions', | 569 option_parser.add_option('--ignore-suppressions', |
544 action='store_true', | 570 action='store_true', |
545 default=False, | 571 default=False, |
546 help='Ignore path-specific license whitelist.') | 572 help='Ignore path-specific license whitelist.') |
547 option_parser.add_option('--json', help='Path to JSON output file') | 573 option_parser.add_option('--json', help='Path to JSON output file') |
548 options, args = option_parser.parse_args() | 574 options, args = option_parser.parse_args() |
549 return check_licenses(options, args) | 575 return check_licenses(options, args) |
550 | 576 |
551 | 577 |
552 if '__main__' == __name__: | 578 if '__main__' == __name__: |
553 sys.exit(main()) | 579 sys.exit(main()) |
OLD | NEW |