Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 #!/usr/bin/python | |
| 2 # Copyright (c) 2010 The Chromium Authors. All rights reserved. | |
| 3 # Use of this source code is governed by a BSD-style license that can be | |
| 4 # found in the LICENSE file. | |
| 5 | |
| 6 """ | |
| 7 Utilities for checking and processing licensing information in third_party | |
| 8 directories. | |
| 9 """ | |
| 10 | |
| 11 import os | |
| 12 | |
| 13 | |
| 14 class LicenseError(Exception): | |
| 15 """We raise this exception when a directory's licensing info isn't | |
| 16 fully filled out.""" | |
| 17 pass | |
| 18 | |
| 19 | |
| 20 def ParseDir(path): | |
| 21 """Examine a third_party/foo component and extract its metadata.""" | |
| 22 | |
| 23 # Try to find README.chromium. | |
| 24 readme_path = os.path.join(path, 'README.chromium') | |
| 25 if not os.path.exists(readme_path): | |
| 26 raise LicenseError("missing README.chromium") | |
| 27 | |
| 28 # Parse metadata fields out of README.chromium. | |
| 29 metadata = { | |
| 30 "License File": None, # Relative path to license text. | |
| 31 "Name": None, # Short name (for header on about:credits). | |
| 32 "URL": None, # Project home page. | |
| 33 } | |
| 34 for line in open(readme_path): | |
| 35 line = line.strip() | |
| 36 for key in metadata.keys(): | |
| 37 field = key + ": " | |
| 38 if line.startswith(field): | |
| 39 metadata[key] = line[len(field):] | |
| 40 | |
| 41 # Check that all expected metadata is present. | |
| 42 for key, value in metadata.iteritems(): | |
| 43 if not value: | |
| 44 raise LicenseError("couldn't find '" + key + "' line " | |
| 45 "in README.chromium") | |
| 46 | |
| 47 # Check that the license file exists. | |
| 48 license_file = metadata["License File"] | |
| 49 license_path = os.path.join(path, license_file) | |
| 50 if not os.path.exists(license_path): | |
| 51 raise LicenseError("README.chromium mentions license file '" + | |
| 52 license_file + "' that doesn't exist") | |
| 53 | |
| 54 return metadata | |
| 55 | |
| 56 | |
| 57 def ScanThirdPartyDirs(third_party_dirs): | |
| 58 """Scan a list of directories and report on any problems we find.""" | |
| 59 errors = [] | |
| 60 for path in sorted(third_party_dirs): | |
| 61 try: | |
| 62 metadata = ParseDir(path) | |
| 63 except LicenseError, e: | |
| 64 errors.append((path, e.args[0])) | |
| 65 continue | |
| 66 print path, "OK:", metadata["License File"] | |
| 67 | |
| 68 for path, error in sorted(errors): | |
| 69 print path + ": " + error | |
| 70 | |
| 71 | |
| 72 def FindThirdPartyDirs(): | |
| 73 """Find all third_party directories underneath the current directory.""" | |
| 74 skip_dirs = ('.svn', '.git', # VCS metadata | |
|
agl
2010/03/18 21:27:05
This could be a set() these days. (Unimportant)
| |
| 75 'out', 'Debug', 'Release', # build files | |
| 76 'layout_tests') # lots of subdirs | |
| 77 | |
| 78 third_party_dirs = [] | |
| 79 for path, dirs, files in os.walk('.'): | |
| 80 path = path[len('./'):] # Pretty up the path. | |
| 81 | |
| 82 # Prune out directories we want to skip. | |
| 83 for skip in skip_dirs: | |
|
agl
2010/03/18 21:27:05
If you make it a set, the order of these loops sho
| |
| 84 if skip in dirs: | |
| 85 dirs.remove(skip) | |
| 86 | |
| 87 if os.path.basename(path) == 'third_party': | |
| 88 third_party_dirs.extend([os.path.join(path, dir) for dir in dirs]) | |
| 89 # Don't recurse into any subdirs from here. | |
| 90 dirs[:] = [] | |
| 91 continue | |
| 92 | |
| 93 return third_party_dirs | |
| 94 | |
| 95 | |
| 96 if __name__ == '__main__': | |
| 97 third_party_dirs = FindThirdPartyDirs() | |
| 98 ScanThirdPartyDirs(third_party_dirs) | |
| OLD | NEW |