Chromium Code Reviews| 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 """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 |
| (...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 247 if filename.startswith('/'): | 247 if filename.startswith('/'): |
| 248 # Absolute-looking paths are relative to the source root | 248 # Absolute-looking paths are relative to the source root |
| 249 # (which is the directory we're run from). | 249 # (which is the directory we're run from). |
| 250 absolute_path = os.path.join(root, filename[1:]) | 250 absolute_path = os.path.join(root, filename[1:]) |
| 251 else: | 251 else: |
| 252 absolute_path = os.path.join(root, path, filename) | 252 absolute_path = os.path.join(root, path, filename) |
| 253 if os.path.exists(absolute_path): | 253 if os.path.exists(absolute_path): |
| 254 return absolute_path | 254 return absolute_path |
| 255 return None | 255 return None |
| 256 | 256 |
| 257 def ParseDir(path, root, require_license_file=True): | 257 def ParseDir(path, root, require_license_file=True, optional_keys=None): |
| 258 """Examine a third_party/foo component and extract its metadata.""" | 258 """Examine a third_party/foo component and extract its metadata.""" |
| 259 | 259 |
| 260 # Parse metadata fields out of README.chromium. | 260 # Parse metadata fields out of README.chromium. |
| 261 # We examine "LICENSE" for the license file by default. | 261 # We examine "LICENSE" for the license file by default. |
| 262 metadata = { | 262 metadata = { |
| 263 "License File": "LICENSE", # Relative path to license text. | 263 "License File": "LICENSE", # Relative path to license text. |
| 264 "Name": None, # Short name (for header on about:credits). | 264 "Name": None, # Short name (for header on about:credits). |
| 265 "URL": None, # Project home page. | 265 "URL": None, # Project home page. |
| 266 "License": None, # Software license. | 266 "License": None, # Software license. |
| 267 } | 267 } |
| 268 | 268 |
| 269 # Relative path to a file containing some html we're required to place in | 269 if optional_keys is None: |
| 270 # about:credits. | 270 optional_keys = [] |
| 271 optional_keys = ["Required Text", "License Android Compatible"] | |
| 272 | 271 |
| 273 if path in SPECIAL_CASES: | 272 if path in SPECIAL_CASES: |
| 274 metadata.update(SPECIAL_CASES[path]) | 273 metadata.update(SPECIAL_CASES[path]) |
| 275 else: | 274 else: |
| 276 # Try to find README.chromium. | 275 # Try to find README.chromium. |
| 277 readme_path = os.path.join(root, path, 'README.chromium') | 276 readme_path = os.path.join(root, path, 'README.chromium') |
| 278 if not os.path.exists(readme_path): | 277 if not os.path.exists(readme_path): |
| 279 raise LicenseError("missing README.chromium or licenses.py " | 278 raise LicenseError("missing README.chromium or licenses.py " |
| 280 "SPECIAL_CASES entry") | 279 "SPECIAL_CASES entry") |
| 281 | 280 |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 305 break | 304 break |
| 306 | 305 |
| 307 if require_license_file and not license_path: | 306 if require_license_file and not license_path: |
| 308 raise LicenseError("License file not found. " | 307 raise LicenseError("License file not found. " |
| 309 "Either add a file named LICENSE, " | 308 "Either add a file named LICENSE, " |
| 310 "import upstream's COPYING if available, " | 309 "import upstream's COPYING if available, " |
| 311 "or add a 'License File:' line to " | 310 "or add a 'License File:' line to " |
| 312 "README.chromium with the appropriate path.") | 311 "README.chromium with the appropriate path.") |
| 313 metadata["License File"] = license_path | 312 metadata["License File"] = license_path |
| 314 | 313 |
| 315 if "Required Text" in metadata: | |
| 316 required_path = AbsolutePath(path, metadata["Required Text"], root) | |
| 317 if required_path is not None: | |
| 318 metadata["Required Text"] = required_path | |
| 319 else: | |
| 320 raise LicenseError("Required text file listed but not found.") | |
| 321 | |
| 322 return metadata | 314 return metadata |
| 323 | 315 |
| 324 | 316 |
| 325 def ContainsFiles(path, root): | 317 def ContainsFiles(path, root): |
| 326 """Determines whether any files exist in a directory or in any of its | 318 """Determines whether any files exist in a directory or in any of its |
| 327 subdirectories.""" | 319 subdirectories.""" |
| 328 for _, dirs, files in os.walk(os.path.join(root, path)): | 320 for _, dirs, files in os.walk(os.path.join(root, path)): |
| 329 if files: | 321 if files: |
| 330 return True | 322 return True |
| 331 for vcs_metadata in VCS_METADATA_DIRS: | 323 for vcs_metadata in VCS_METADATA_DIRS: |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 418 return template | 410 return template |
| 419 | 411 |
| 420 root = os.path.join(os.path.dirname(__file__), '..') | 412 root = os.path.join(os.path.dirname(__file__), '..') |
| 421 third_party_dirs = FindThirdPartyDirs(PRUNE_PATHS, root) | 413 third_party_dirs = FindThirdPartyDirs(PRUNE_PATHS, root) |
| 422 | 414 |
| 423 entry_template = open(os.path.join(root, 'chrome', 'browser', 'resources', | 415 entry_template = open(os.path.join(root, 'chrome', 'browser', 'resources', |
| 424 'about_credits_entry.tmpl'), 'rb').read() | 416 'about_credits_entry.tmpl'), 'rb').read() |
| 425 entries = [] | 417 entries = [] |
| 426 for path in sorted(third_party_dirs): | 418 for path in sorted(third_party_dirs): |
| 427 try: | 419 try: |
| 428 metadata = ParseDir(path, root) | 420 metadata = ParseDir(path, root, optional_keys=['Required Text']) |
| 429 except LicenseError: | 421 except LicenseError: |
| 430 # TODO(phajdan.jr): Convert to fatal error (http://crbug.com/39240). | 422 # TODO(phajdan.jr): Convert to fatal error (http://crbug.com/39240). |
| 431 continue | 423 continue |
| 432 if metadata['License File'] == NOT_SHIPPED: | 424 if metadata['License File'] == NOT_SHIPPED: |
| 433 continue | 425 continue |
| 434 env = { | 426 env = { |
| 435 'name': metadata['Name'], | 427 'name': metadata['Name'], |
| 436 'url': metadata['URL'], | 428 'url': metadata['URL'], |
| 437 'license': open(metadata['License File'], 'rb').read(), | 429 'license': open(metadata['License File'], 'rb').read(), |
| 438 'license_unescaped': '', | 430 'license_unescaped': '', |
| 439 } | 431 } |
| 432 # 'Required Text' is a relative path to a file containing some html | |
|
Lei Zhang
2014/10/30 09:14:11
Fun fact, nobody uses this anymore. It was added s
mckev
2014/10/30 16:45:13
Interesting. Would you advocate removing it now,
Lei Zhang
2014/10/30 19:06:13
I'd just remove it and mention it in the CL descri
mckev
2014/10/30 20:45:54
Sounds good to me!
| |
| 433 # we're required to place in about:credits. | |
| 440 if 'Required Text' in metadata: | 434 if 'Required Text' in metadata: |
| 441 required_text = open(metadata['Required Text'], 'rb').read() | 435 required_path = AbsolutePath(path, metadata["Required Text"], root) |
| 436 if required_path is not None: | |
| 437 required_text = open(required_path, 'rb').read() | |
| 438 else: | |
| 439 # TODO(phajdan.jr): Convert to fatal error (http://crbug.com/392 40). | |
|
Lei Zhang
2014/10/30 09:14:11
BTW, 79 chars / line in general with Python. See P
mckev
2014/10/30 16:45:13
Whoops, sorry about that. I'll fix it right away.
| |
| 440 continue | |
| 442 env["license_unescaped"] = required_text | 441 env["license_unescaped"] = required_text |
| 443 entries.append(EvaluateTemplate(entry_template, env)) | 442 entries.append(EvaluateTemplate(entry_template, env)) |
| 444 | 443 |
| 445 file_template = open(os.path.join(root, 'chrome', 'browser', 'resources', | 444 file_template = open(os.path.join(root, 'chrome', 'browser', 'resources', |
| 446 'about_credits.tmpl'), 'rb').read() | 445 'about_credits.tmpl'), 'rb').read() |
| 447 template_contents = "<!-- Generated by licenses.py; do not edit. -->" | 446 template_contents = "<!-- Generated by licenses.py; do not edit. -->" |
| 448 template_contents += EvaluateTemplate(file_template, | 447 template_contents += EvaluateTemplate(file_template, |
| 449 {'entries': '\n'.join(entries)}, | 448 {'entries': '\n'.join(entries)}, |
| 450 escape=False) | 449 escape=False) |
| 451 | 450 |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 469 elif command == 'credits': | 468 elif command == 'credits': |
| 470 if not GenerateCredits(): | 469 if not GenerateCredits(): |
| 471 return 1 | 470 return 1 |
| 472 else: | 471 else: |
| 473 print __doc__ | 472 print __doc__ |
| 474 return 1 | 473 return 1 |
| 475 | 474 |
| 476 | 475 |
| 477 if __name__ == '__main__': | 476 if __name__ == '__main__': |
| 478 sys.exit(main()) | 477 sys.exit(main()) |
| OLD | NEW |