epoger@google.com | 935d945 | 2011-07-28 14:29:58 +0000 | [diff] [blame] | 1 | ''' |
| 2 | Copyright 2011 Google Inc. |
| 3 | |
| 4 | Use of this source code is governed by a BSD-style license that can be |
| 5 | found in the LICENSE file. |
| 6 | ''' |
| 7 | |
| 8 | ''' |
| 9 | Updates all copyright headers within our code: |
| 10 | - For files that already have a copyright header, the header is modified |
| 11 | while keeping the year and holder intact. |
| 12 | - For files that don't have a copyright header, we add one with the current |
| 13 | year and default holder. |
| 14 | |
| 15 | @author: epoger@google.com |
| 16 | ''' |
| 17 | |
| 18 | import os |
| 19 | import sys |
| 20 | |
| 21 | import fileparser |
| 22 | |
| 23 | # Only modify copyright stanzas if the copyright holder is one of these. |
| 24 | ALLOWED_COPYRIGHT_HOLDERS = [ |
| 25 | 'Google Inc.', |
| 26 | 'Skia', |
| 27 | 'The Android Open Source Project', |
| 28 | ] |
| 29 | |
| 30 | def Main(root_directory): |
| 31 | """Run everything. |
| 32 | |
| 33 | @param root_directory root directory within which to modify all files |
| 34 | """ |
| 35 | filepaths = GetAllFilepaths(root_directory) |
| 36 | for filepath in filepaths: |
| 37 | parser = fileparser.CreateParser(filepath) |
| 38 | if not parser: |
| 39 | ReportWarning('cannot find a parser for file %s, skipping...' % |
| 40 | filepath) |
| 41 | continue |
| 42 | old_file_contents = ReadFileIntoString(filepath) |
| 43 | comment_blocks = parser.FindAllCommentBlocks(old_file_contents) |
| 44 | if not comment_blocks: |
| 45 | ReportWarning('cannot find any comment blocks in file %s' % |
| 46 | filepath) |
| 47 | old_copyright_block = parser.FindCopyrightBlock(comment_blocks) |
| 48 | if not old_copyright_block: |
| 49 | ReportWarning('cannot find copyright block in file %s' % filepath) |
| 50 | (year, holder) = parser.GetCopyrightBlockAttributes(old_copyright_block) |
| 51 | if holder and not ConfirmAllowedCopyrightHolder(holder): |
| 52 | ReportWarning( |
| 53 | 'unrecognized copyright holder "%s" in file %s, skipping...' % ( |
| 54 | holder, filepath)) |
| 55 | continue |
| 56 | new_copyright_block = parser.CreateCopyrightBlock(year, holder) |
| 57 | if old_copyright_block: |
| 58 | new_file_contents = old_file_contents.replace( |
| 59 | old_copyright_block, new_copyright_block, 1) |
| 60 | else: |
| 61 | new_file_contents = new_copyright_block + old_file_contents |
| 62 | WriteStringToFile(new_file_contents, filepath) |
| 63 | |
| 64 | def GetAllFilepaths(root_directory): |
| 65 | """Return a list of all files (absolute path for each one) within a tree. |
| 66 | |
| 67 | @param root_directory root directory within which to find all files |
| 68 | """ |
| 69 | path_list = [] |
| 70 | for dirpath, dirnames, filenames in os.walk(root_directory): |
| 71 | for filename in filenames: |
| 72 | path_list.append(os.path.abspath(os.path.join(dirpath, filename))) |
| 73 | return path_list |
| 74 | |
| 75 | def ReportWarning(text): |
| 76 | """Report a warning, but continue. |
| 77 | """ |
| 78 | print 'warning: %s' % text |
| 79 | |
| 80 | def ReportError(text): |
| 81 | """Report an error and raise an exception. |
| 82 | """ |
| 83 | raise IOError(text) |
| 84 | |
| 85 | def ReadFileIntoString(filepath): |
| 86 | """Returns the full contents of this file as a string. |
| 87 | """ |
| 88 | with open(filepath, 'r') as file_handle: |
| 89 | contents = file_handle.read() |
| 90 | return contents |
| 91 | |
| 92 | def WriteStringToFile(string, filepath): |
| 93 | """Writes this string out to filepath, replacing the file if it already |
| 94 | exists. |
| 95 | """ |
| 96 | with open(filepath, 'w') as file_handle: |
| 97 | file_handle.write(string) |
| 98 | |
| 99 | def ConfirmAllowedCopyrightHolder(holder): |
| 100 | """Returns True if this is one of our allowed copyright holders. |
| 101 | |
| 102 | @param holder copyright holder as a string |
| 103 | """ |
| 104 | return holder in ALLOWED_COPYRIGHT_HOLDERS |
| 105 | |
| 106 | |
| 107 | Main(sys.argv[1]) |