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

Side by Side Diff: git-try

Issue 516007: Rips the guts out of git-try since trychange.py is now supper awesome. (Closed)
Patch Set: Created 11 years 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) 2009 The Chromium Authors. All rights reserved. 2 # Copyright (c) 2009 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 """Wrapper for trychange.py for git checkout.""" 5 """Wrapper for trychange.py for git checkout."""
6 6
7 import getpass
8 import optparse
9 import os
10 import re
11 import subprocess
12 import sys 7 import sys
13 import tempfile
14 import traceback
15 import urllib
16 8
17 import breakpad 9 try:
10 import breakpad
11 except ImportError:
12 pass
18 13
14 from scm import GIT
19 import trychange 15 import trychange
20 16
21 17
22 def Backquote(cmd, cwd=None):
23 """Like running `cmd` in a shell script."""
24 return subprocess.Popen(cmd,
25 cwd=cwd,
26 stdout=subprocess.PIPE).communicate()[0].strip()
27
28
29 def GetTryServerConfig():
30 """Returns the dictionary of try server options or None if they
31 cannot be found."""
32 script_path = 'tools/tryserver/tryserver.py'
33 root_dir = Backquote(['git', 'rev-parse', '--show-cdup'])
34 try:
35 script_file = open(os.path.join(root_dir, script_path))
36 except IOError:
37 return None
38 locals = {}
39 try:
40 exec(script_file, locals)
41 except Exception, e:
42 return None
43 return locals
44
45
46 def GetBranchName(working_dir=None):
47 """Return name of current git branch."""
48 branch = Backquote(['git', 'symbolic-ref', 'HEAD'], working_dir)
49 if not branch.startswith('refs/heads/'):
50 raise "Couldn't figure out branch name"
51 branch = branch[len('refs/heads/'):]
52 return branch
53
54
55 def GetPatchName(working_dir=None):
56 """Construct a name for this patch."""
57 short_sha = Backquote(['git', 'rev-parse', '--short=4', 'HEAD'], working_dir)
58 return GetBranchName() + '-' + short_sha
59
60
61 def GetRietveldIssueNumber(): 18 def GetRietveldIssueNumber():
62 return Backquote(['git', 'config', 19 return GIT.Capture(
63 'branch.%s.rietveldissue' % GetBranchName()]) 20 ['config', 'branch.%s.rietveldissue' % GIT.GetBranch(None)],
21 error_ok=True)
64 22
65 23
66 def GetRietveldPatchsetNumber(): 24 def GetRietveldPatchsetNumber():
67 return Backquote(['git', 'config', 25 return GIT.Capture(
68 'branch.%s.rietveldpatchset' % GetBranchName()]) 26 ['config', 'branch.%s.rietveldpatchset' % GIT.GetBranch(None)],
69 27 error_ok=True)
70 def GetSubRepWorkingDir(sub_rep_path):
71 """Computes the path to the sub repository"""
72 if sub_rep_path:
73 root_dir = os.path.abspath(Backquote(['git', 'rev-parse', '--show-cdup']))
74 return os.path.join(root_dir, sub_rep_path)
75 return None
76
77 def GetMungedDiff(branch, prefix, sub_rep_path):
78 """Get the diff we'll send to the try server. We munge paths to match svn.
79 We add the prefix that the try bot is expecting. If sub_rep_path is
80 provided, diff will be calculated in the sub repository.
81 We also return the list of files in this diff, without munged paths."""
82 # Make the following changes:
83 # - Prepend "src/" (or some other prefix) to paths as svn is expecting
84 # - In the case of added files, replace /dev/null with the path to the file
85 # being added.
86
87 cwd = GetSubRepWorkingDir(sub_rep_path)
88
89 output = []
90 if not branch:
91 # Try to guess the upstream branch.
92 branch = Backquote(['git', 'cl', 'upstream'], cwd)
93 command = ['git', 'diff-tree', '-p']
94
95 new_cwd = None
96 if not sub_rep_path:
97 command.extend(['--no-prefix'])
98 else:
99 # Append /
100 sub_rep_path = os.path.join(sub_rep_path, '')
101 # Add the right prefix
102 command.extend(['--src-prefix=' + sub_rep_path])
103 command.extend(['--dst-prefix=' + sub_rep_path])
104
105 command.extend([branch, 'HEAD'])
106
107 # Run diff tree
108 diff = subprocess.Popen(command,
109 stdout=subprocess.PIPE,
110 cwd=cwd).stdout.readlines()
111 # Replace --- /dev/null with --- <new file name>
112 for i in range(len(diff)):
113 line = diff[i]
114 if line.startswith('--- /dev/null'):
115 line = '--- %s' % diff[i+1][4:]
116 output.append(line)
117 diff = output
118
119 # Add root prefix
120 output = []
121 file_set = set()
122 for line in diff:
123 if line.startswith('--- ') or line.startswith('+++ '):
124 filename = line[4:]
125 line = line[0:4] + os.path.join(prefix, filename)
126 file_set.add(filename.rstrip('\r\n'))
127 output.append(line)
128
129 munged_diff = ''.join(output)
130 if len(munged_diff.strip()) == 0:
131 raise Exception("Patch was empty, did you give the right remote branch?")
132
133 return (munged_diff, list(file_set))
134
135 def OneRepositoryDiff(diff_file, patch_names, branch, prefix, sub_rep_path):
136 """Computes a diff for one git repository at a given path against a given
137 branch. Writes the diff into diff_file and appends a name to the
138 patch_names list.
139
140 Returns the list of files in the diff."""
141
142 (diff, file_list) = GetMungedDiff(branch, prefix, sub_rep_path)
143
144 # Write the diff out
145 diff_file.write(diff)
146
147 # Add patch name to list of patches
148 patch_name = GetPatchName(GetSubRepWorkingDir(sub_rep_path))
149 patch_names.extend([patch_name])
150 return file_list
151
152
153 def ValidEmail(email):
154 return re.match(r"^[a-zA-Z0-9._%-+]+@[a-zA-Z0-9._%-]+.[a-zA-Z]{2,6}$", email)
155
156
157 def GetEmail():
158 email = Backquote(['git', 'config', 'user.email'])
159 runmsg = "Try: git config user.email <EMAIL>"
160 assert ValidEmail(email), "Email '%s' is not valid. %s" % (email, runmsg)
161 return email
162
163
164 def TryChange(args, file_list):
165 """Put a patch on the try server."""
166 trychange.TryChange(args, file_list, False)
167 28
168 29
169 if __name__ == '__main__': 30 if __name__ == '__main__':
170 parser = optparse.OptionParser( 31 args = sys.argv[:]
171 usage='git try [options] [branch]', 32 patchset = GetRietveldPatchsetNumber()
172 description='Upload the current diff of branch...HEAD to the try server.') 33 if patchset:
173 parser.add_option("-b", "--bot", action="append",
174 help="Force the use of a specific build slave (eg mac, "
175 "win, or linux)")
176 parser.add_option("-c", "--clobber", action="store_true",
177 help="Make the try run use be a clobber build")
178 parser.add_option("-r", "--revision",
179 help="Specify the SVN base revision to use")
180 parser.add_option("--root", default="src", metavar="PATH",
181 help="Specify the root prefix that is prepended to paths "
182 "in the patch")
183 parser.add_option("--dry_run", action="store_true",
184 help="Print the diff but don't send it to the try bots")
185 parser.add_option("--sub_rep", nargs=2, action="append", default=[],
186 metavar="PATH BRANCH",
187 help="Specify a path to a git sub-repository and a branch "
188 "to diff with in order to simultanously try changes "
189 "in multiple git repositories. Option may be "
190 "specified multiple times.")
191 parser.add_option("--webkit", metavar="BRANCH",
192 help="Specify webkit branch. Syntactic sugar for "
193 "--sub_rep third_party/WebKit/ <branch>")
194
195 (options, args) = parser.parse_args(sys.argv)
196
197 if options.webkit:
198 options.sub_rep.extend([('third_party/WebKit/', options.webkit)])
199
200 branch = None
201 if len(args) > 1:
202 branch = args[1]
203 patch_names = []
204
205 # Dump all diffs into one diff file.
206 diff_file = tempfile.NamedTemporaryFile()
207
208 # Calculate diff for main git repository.
209 file_list = OneRepositoryDiff(diff_file, patch_names, branch, options.root,
210 None)
211
212 # Calculate diff for each extra git repository.
213 for path_and_branch in options.sub_rep:
214 file_list.extend(OneRepositoryDiff(diff_file,
215 patch_names,
216 path_and_branch[1],
217 options.root,
218 path_and_branch[0]))
219 # Make diff file ready for reading.
220 diff_file.flush()
221
222 # Concatenate patch names
223 # Prepare args for TryChange
224 email = GetEmail()
225 user = email.partition('@')[0]
226 args = [
227 '-u', user,
228 '-e', email,
229 '-n', '-'.join(patch_names),
230 '--diff', diff_file.name,
231 ]
232
233 # Send to try server via HTTP if we can parse the config, otherwise
234 # upload via SVN.
235 config = GetTryServerConfig()
236 if config is not None:
237 sendmsg = "Sending %s using HTTP..." % '-'.join(patch_names)
238 args.extend(['--use_http'])
239 if config['try_server_http_host'] is not None:
240 args.extend(['--host', config['try_server_http_host']])
241 if config['try_server_http_port'] is not None:
242 args.extend(['--port', config['try_server_http_port']])
243
244 else:
245 print "Could not get server config -- if you're within Google, "
246 print "do you have have src-internal checked out?"
247 sendmsg = "Sending %s using SVN..." % '-'.join(patch_names)
248 args.extend([
249 '--use_svn', '--svn_repo',
250 'svn://svn.chromium.org/chrome-try/try',
251 ])
252
253 if options.bot:
254 for bot in options.bot:
255 args.extend(['--bot', bot])
256 if options.clobber:
257 args.append('--clobber')
258 if options.revision:
259 args.extend(['-r', options.revision])
260 if GetRietveldPatchsetNumber():
261 args.extend([ 34 args.extend([
262 '--issue', GetRietveldIssueNumber(), 35 '--issue', GetRietveldIssueNumber(),
263 '--patchset', GetRietveldPatchsetNumber(), 36 '--patchset', patchset,
264 ]) 37 ])
265 38 sys.exit(trychange.TryChange(args, [], False, 'git-try'))
266 if options.dry_run:
267 print open(diff_file.name, 'r').read()
268 exit(0)
269
270 print sendmsg
271 TryChange(args, file_list)
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