xref: /aosp_15_r20/external/jsoncpp/devtools/licenseupdater.py (revision 4484440890e2bc6e07362b4feaf15601abfe0071)
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