1*44844408SAndroid Build Coastguard Worker"""Updates the license text in source file. 2*44844408SAndroid Build Coastguard Worker""" 3*44844408SAndroid Build Coastguard Workerfrom __future__ import print_function 4*44844408SAndroid Build Coastguard Worker 5*44844408SAndroid Build Coastguard Worker# An existing license is found if the file starts with the string below, 6*44844408SAndroid Build Coastguard Worker# and ends with the first blank line. 7*44844408SAndroid Build Coastguard WorkerLICENSE_BEGIN = "// Copyright " 8*44844408SAndroid Build Coastguard Worker 9*44844408SAndroid Build Coastguard WorkerBRIEF_LICENSE = LICENSE_BEGIN + """2007-2010 Baptiste Lepilleur and The JsonCpp Authors 10*44844408SAndroid Build Coastguard Worker// Distributed under MIT license, or public domain if desired and 11*44844408SAndroid Build Coastguard Worker// recognized in your jurisdiction. 12*44844408SAndroid Build Coastguard Worker// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE 13*44844408SAndroid Build Coastguard Worker 14*44844408SAndroid Build Coastguard Worker""".replace('\r\n','\n') 15*44844408SAndroid Build Coastguard Worker 16*44844408SAndroid Build Coastguard Workerdef update_license(path, dry_run, show_diff): 17*44844408SAndroid Build Coastguard Worker """Update the license statement in the specified file. 18*44844408SAndroid Build Coastguard Worker Parameters: 19*44844408SAndroid Build Coastguard Worker path: path of the C++ source file to update. 20*44844408SAndroid Build Coastguard Worker dry_run: if True, just print the path of the file that would be updated, 21*44844408SAndroid Build Coastguard Worker but don't change it. 22*44844408SAndroid Build Coastguard Worker show_diff: if True, print the path of the file that would be modified, 23*44844408SAndroid Build Coastguard Worker as well as the change made to the file. 24*44844408SAndroid Build Coastguard Worker """ 25*44844408SAndroid Build Coastguard Worker with open(path, 'rt') as fin: 26*44844408SAndroid Build Coastguard Worker original_text = fin.read().replace('\r\n','\n') 27*44844408SAndroid Build Coastguard Worker newline = fin.newlines and fin.newlines[0] or '\n' 28*44844408SAndroid Build Coastguard Worker if not original_text.startswith(LICENSE_BEGIN): 29*44844408SAndroid Build Coastguard Worker # No existing license found => prepend it 30*44844408SAndroid Build Coastguard Worker new_text = BRIEF_LICENSE + original_text 31*44844408SAndroid Build Coastguard Worker else: 32*44844408SAndroid Build Coastguard Worker license_end_index = original_text.index('\n\n') # search first blank line 33*44844408SAndroid Build Coastguard Worker new_text = BRIEF_LICENSE + original_text[license_end_index+2:] 34*44844408SAndroid Build Coastguard Worker if original_text != new_text: 35*44844408SAndroid Build Coastguard Worker if not dry_run: 36*44844408SAndroid Build Coastguard Worker with open(path, 'wb') as fout: 37*44844408SAndroid Build Coastguard Worker fout.write(new_text.replace('\n', newline)) 38*44844408SAndroid Build Coastguard Worker print('Updated', path) 39*44844408SAndroid Build Coastguard Worker if show_diff: 40*44844408SAndroid Build Coastguard Worker import difflib 41*44844408SAndroid Build Coastguard Worker print('\n'.join(difflib.unified_diff(original_text.split('\n'), 42*44844408SAndroid Build Coastguard Worker new_text.split('\n')))) 43*44844408SAndroid Build Coastguard Worker return True 44*44844408SAndroid Build Coastguard Worker return False 45*44844408SAndroid Build Coastguard Worker 46*44844408SAndroid Build Coastguard Workerdef update_license_in_source_directories(source_dirs, dry_run, show_diff): 47*44844408SAndroid Build Coastguard Worker """Updates license text in C++ source files found in directory source_dirs. 48*44844408SAndroid Build Coastguard Worker Parameters: 49*44844408SAndroid Build Coastguard Worker source_dirs: list of directory to scan for C++ sources. Directories are 50*44844408SAndroid Build Coastguard Worker scanned recursively. 51*44844408SAndroid Build Coastguard Worker dry_run: if True, just print the path of the file that would be updated, 52*44844408SAndroid Build Coastguard Worker but don't change it. 53*44844408SAndroid Build Coastguard Worker show_diff: if True, print the path of the file that would be modified, 54*44844408SAndroid Build Coastguard Worker as well as the change made to the file. 55*44844408SAndroid Build Coastguard Worker """ 56*44844408SAndroid Build Coastguard Worker from devtools import antglob 57*44844408SAndroid Build Coastguard Worker prune_dirs = antglob.prune_dirs + 'scons-local* ./build* ./libs ./dist' 58*44844408SAndroid Build Coastguard Worker for source_dir in source_dirs: 59*44844408SAndroid Build Coastguard Worker cpp_sources = antglob.glob(source_dir, 60*44844408SAndroid Build Coastguard Worker includes = '''**/*.h **/*.cpp **/*.inl''', 61*44844408SAndroid Build Coastguard Worker prune_dirs = prune_dirs) 62*44844408SAndroid Build Coastguard Worker for source in cpp_sources: 63*44844408SAndroid Build Coastguard Worker update_license(source, dry_run, show_diff) 64*44844408SAndroid Build Coastguard Worker 65*44844408SAndroid Build Coastguard Workerdef main(): 66*44844408SAndroid Build Coastguard Worker usage = """%prog DIR [DIR2...] 67*44844408SAndroid Build Coastguard WorkerUpdates license text in sources of the project in source files found 68*44844408SAndroid Build Coastguard Workerin the directory specified on the command-line. 69*44844408SAndroid Build Coastguard Worker 70*44844408SAndroid Build Coastguard WorkerExample of call: 71*44844408SAndroid Build Coastguard Workerpython devtools\licenseupdater.py include src -n --diff 72*44844408SAndroid Build Coastguard Worker=> Show change that would be made to the sources. 73*44844408SAndroid Build Coastguard Worker 74*44844408SAndroid Build Coastguard Workerpython devtools\licenseupdater.py include src 75*44844408SAndroid Build Coastguard Worker=> Update license statement on all sources in directories include/ and src/. 76*44844408SAndroid Build Coastguard Worker""" 77*44844408SAndroid Build Coastguard Worker from optparse import OptionParser 78*44844408SAndroid Build Coastguard Worker parser = OptionParser(usage=usage) 79*44844408SAndroid Build Coastguard Worker parser.allow_interspersed_args = False 80*44844408SAndroid Build Coastguard Worker parser.add_option('-n', '--dry-run', dest="dry_run", action='store_true', default=False, 81*44844408SAndroid Build Coastguard Worker help="""Only show what files are updated, do not update the files""") 82*44844408SAndroid Build Coastguard Worker parser.add_option('--diff', dest="show_diff", action='store_true', default=False, 83*44844408SAndroid Build Coastguard Worker help="""On update, show change made to the file.""") 84*44844408SAndroid Build Coastguard Worker parser.enable_interspersed_args() 85*44844408SAndroid Build Coastguard Worker options, args = parser.parse_args() 86*44844408SAndroid Build Coastguard Worker update_license_in_source_directories(args, options.dry_run, options.show_diff) 87*44844408SAndroid Build Coastguard Worker print('Done') 88*44844408SAndroid Build Coastguard Worker 89*44844408SAndroid Build Coastguard Workerif __name__ == '__main__': 90*44844408SAndroid Build Coastguard Worker import sys 91*44844408SAndroid Build Coastguard Worker import os.path 92*44844408SAndroid Build Coastguard Worker sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) 93*44844408SAndroid Build Coastguard Worker main() 94*44844408SAndroid Build Coastguard Worker 95