1 #! /usr/bin/env python3
2
3 """(Ostensibly) fix copyright notices in files.
4
5 Actually, this script will simply replace a block of text in a file from one
6 string to another. It will only do this once though, i.e. not globally
7 throughout the file. It writes a backup file and then does an os.rename()
8 dance for atomicity.
9
10 Usage: fixnotices.py [options] [filenames]
11 Options:
12 -h / --help
13 Print this message and exit
14
15 --oldnotice=file
16 Use the notice in the file as the old (to be replaced) string, instead
17 of the hard coded value in the script.
18
19 --newnotice=file
20 Use the notice in the file as the new (replacement) string, instead of
21 the hard coded value in the script.
22
23 --dry-run
24 Don't actually make the changes, but print out the list of files that
25 would change. When used with -v, a status will be printed for every
26 file.
27
28 -v / --verbose
29 Print a message for every file looked at, indicating whether the file
30 is changed or not.
31 """
32
33 OLD_NOTICE = """/***********************************************************
34 Copyright (c) 2000, BeOpen.com.
35 Copyright (c) 1995-2000, Corporation for National Research Initiatives.
36 Copyright (c) 1990-1995, Stichting Mathematisch Centrum.
37 All rights reserved.
38
39 See the file "Misc/COPYRIGHT" for information on usage and
40 redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
41 ******************************************************************/
42 """
43 import os
44 import sys
45 import getopt
46
47 NEW_NOTICE = ""
48 DRYRUN = 0
49 VERBOSE = 0
50
51
52 def usage(code, msg=''):
53 print(__doc__ % globals())
54 if msg:
55 print(msg)
56 sys.exit(code)
57
58
59 def main():
60 global DRYRUN, OLD_NOTICE, NEW_NOTICE, VERBOSE
61 try:
62 opts, args = getopt.getopt(sys.argv[1:], 'hv',
63 ['help', 'oldnotice=', 'newnotice=',
64 'dry-run', 'verbose'])
65 except getopt.error as msg:
66 usage(1, msg)
67
68 for opt, arg in opts:
69 if opt in ('-h', '--help'):
70 usage(0)
71 elif opt in ('-v', '--verbose'):
72 VERBOSE = 1
73 elif opt == '--dry-run':
74 DRYRUN = 1
75 elif opt == '--oldnotice':
76 with open(arg) as fp:
77 OLD_NOTICE = fp.read()
78 elif opt == '--newnotice':
79 with open(arg) as fp:
80 NEW_NOTICE = fp.read()
81
82 for arg in args:
83 process(arg)
84
85
86 def process(file):
87 with open(file) as f:
88 data = f.read()
89 i = data.find(OLD_NOTICE)
90 if i < 0:
91 if VERBOSE:
92 print('no change:', file)
93 return
94 elif DRYRUN or VERBOSE:
95 print(' change:', file)
96 if DRYRUN:
97 # Don't actually change the file
98 return
99 data = data[:i] + NEW_NOTICE + data[i+len(OLD_NOTICE):]
100 new = file + ".new"
101 backup = file + ".bak"
102 with open(new, "w") as f:
103 f.write(data)
104 os.rename(file, backup)
105 os.rename(new, file)
106
107
108 if __name__ == '__main__':
109 main()