Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(67)

Side by Side Diff: tools/sort-headers.py

Issue 8390055: Lets you run sort-headers.py on all files changed since some git branch. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/python 1 #!/usr/bin/python
2 # Copyright (c) 2011 The Chromium Authors. All rights reserved. 2 # Copyright (c) 2011 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 5
6 """Given a filename as an argument, sort the #include/#imports in that file. 6 """Given a filename as an argument, sort the #include/#imports in that file.
7 7
8 Shows a diff and prompts for confirmation before doing the deed. 8 Shows a diff and prompts for confirmation before doing the deed.
9 """ 9 """
10 10
11 import optparse 11 import optparse
12 import os 12 import os
13 import subprocess
13 import sys 14 import sys
14 import termios 15 import termios
15 import tty 16 import tty
16 17
18 # List of extensions whose headers this script knows how to sort.
19 _SOURCE_EXTENSIONS = ('h', 'hh', 'hpp', 'c', 'cc', 'cpp', 'cxx', 'mm',)
20
17 def YesNo(prompt): 21 def YesNo(prompt):
18 """Prompts with a yes/no question, returns True if yes.""" 22 """Prompts with a yes/no question, returns True if yes."""
19 print prompt, 23 print prompt,
20 sys.stdout.flush() 24 sys.stdout.flush()
21 # http://code.activestate.com/recipes/134892/ 25 # http://code.activestate.com/recipes/134892/
22 fd = sys.stdin.fileno() 26 fd = sys.stdin.fileno()
23 old_settings = termios.tcgetattr(fd) 27 old_settings = termios.tcgetattr(fd)
24 ch = 'n' 28 ch = 'n'
25 try: 29 try:
26 tty.setraw(sys.stdin.fileno()) 30 tty.setraw(sys.stdin.fileno())
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
64 while IsInclude(line): 68 while IsInclude(line):
65 headerblock.append(line) 69 headerblock.append(line)
66 line = infile.next() 70 line = infile.next()
67 for header in sorted(headerblock, key=IncludeCompareKey): 71 for header in sorted(headerblock, key=IncludeCompareKey):
68 outfile.write(header) 72 outfile.write(header)
69 # Intentionally fall through, to write the line that caused 73 # Intentionally fall through, to write the line that caused
70 # the above while loop to exit. 74 # the above while loop to exit.
71 outfile.write(line) 75 outfile.write(line)
72 76
73 77
78 def DiffAndConfirm(filename, should_confirm):
79 fixfilename = filename + '.new'
80 infile = open(filename, 'r')
81 outfile = open(fixfilename, 'w')
82 SortHeader(infile, outfile)
83 infile.close()
84 outfile.close() # Important so the below diff gets the updated contents.
85
86 try:
87 diff = os.system('diff -u %s %s' % (filename, fixfilename))
88 if diff >> 8 == 0: # Check exit code.
89 print '%s: no change' % filename
90 return
91
92 if not should_confirm or YesNo('Use new file (y/N)?'):
93 os.rename(fixfilename, filename)
94 finally:
95 try:
96 os.remove(fixfilename)
97 except OSError:
98 # If the file isn't there, we don't care.
99 pass
100
101
102 def GitShell(args, ignore_return=False):
103 """A shell invocation suitable for communicating with git. Returns
104 output as list of lines, raises exception on error.
105 """
106 job = subprocess.Popen(args,
107 shell=True,
108 stdout=subprocess.PIPE,
109 stderr=subprocess.STDOUT)
110 (out, err) = job.communicate()
111 if job.returncode != 0 and not ignore_return:
112 print out
113 raise Exception("Error %d running command %s" % (
114 job.returncode, args))
115 return out.split('\n')
116
117
118 def FilenamesFromGit(branch_name):
Nico 2011/10/26 17:53:38 Needs docstring
119 lines = GitShell('git diff --stat=600,500 %s' % branch_name)
120 filenames = []
121 for line in lines:
122 line = line.lstrip()
123 # Avoid summary line, and files that have been deleted (no plus).
124 if line.find('|') != -1 and line.find('+') != -1:
125 filename = line.split()[0]
126 if filename:
127 filename = filename.rstrip()
128 ext = filename.rsplit('.')[-1]
129 if ext in _SOURCE_EXTENSIONS:
130 filenames.append(filename)
131 return filenames
132
133
74 def main(): 134 def main():
75 parser = optparse.OptionParser(usage='%prog filename1 filename2 ...') 135 parser = optparse.OptionParser(usage='%prog filename1 filename2 ...')
76 opts, args = parser.parse_args() 136 parser.add_option('-g', '--gitbranch', dest='git_branch',
137 help='Get list of files as diff from git branch.')
138 parser.add_option('-q', '--quiet', action='store_false', default=True,
Nico 2011/10/26 17:53:38 Confirm prompt suppression flags are usually calle
139 dest='should_confirm',
140 help='Turn off confirmation prompt.')
141 opts, filenames = parser.parse_args()
77 142
78 if len(args) < 1: 143 if len(filenames) < 1 and not opts.git_branch:
79 parser.print_help() 144 parser.print_help()
80 sys.exit(1) 145 sys.exit(1)
81 146
82 for filename in args: 147 if opts.git_branch:
83 fixfilename = filename + '.new' 148 filenames = FilenamesFromGit(opts.git_branch)
84 infile = open(filename, 'r')
85 outfile = open(fixfilename, 'w')
86 SortHeader(infile, outfile)
87 infile.close()
88 outfile.close() # Important so the below diff gets the updated contents.
89 149
90 try: 150 for filename in filenames:
91 diff = os.system('diff -u %s %s' % (filename, fixfilename)) 151 DiffAndConfirm(filename, opts.should_confirm)
92 if diff >> 8 == 0: # Check exit code.
93 print '%s: no change' % filename
94 continue
95
96 if YesNo('Use new file (y/N)?'):
97 os.rename(fixfilename, filename)
98 finally:
99 try:
100 os.remove(fixfilename)
101 except OSError:
102 # If the file isn't there, we don't care.
103 pass
104 152
105 153
106 if __name__ == '__main__': 154 if __name__ == '__main__':
107 main() 155 main()
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698