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