Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(32)

Delta Between Two Patch Sets: lib/codereview/codereview.py

Issue 3989059: code review 3989059: codereviwe: make hgpatch working on win32 (Closed)
Left Patch Set: Created 14 years, 2 months ago
Right Patch Set: diff -r 6c45f8ad74dd http://go.googlecode.com/hg/ Created 14 years, 2 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « no previous file | no next file » | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 # coding=utf-8 1 # coding=utf-8
2 # (The line above is necessary so that I can use 世界 in the 2 # (The line above is necessary so that I can use 世界 in the
3 # *comment* below without Python getting all bent out of shape.) 3 # *comment* below without Python getting all bent out of shape.)
4 4
5 # Copyright 2007-2009 Google Inc. 5 # Copyright 2007-2009 Google Inc.
6 # 6 #
7 # Licensed under the Apache License, Version 2.0 (the "License"); 7 # Licensed under the Apache License, Version 2.0 (the "License");
8 # you may not use this file except in compliance with the License. 8 # you may not use this file except in compliance with the License.
9 # You may obtain a copy of the License at 9 # You may obtain a copy of the License at
10 # 10 #
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after
246 s += "\tReviewer: " + JoinComma(cl.reviewer) + "\n" 246 s += "\tReviewer: " + JoinComma(cl.reviewer) + "\n"
247 s += "\tCC: " + JoinComma(cl.cc) + "\n" 247 s += "\tCC: " + JoinComma(cl.cc) + "\n"
248 s += "\tFiles:\n" 248 s += "\tFiles:\n"
249 for f in cl.files: 249 for f in cl.files:
250 s += "\t\t" + f + "\n" 250 s += "\t\t" + f + "\n"
251 typecheck(s, str) 251 typecheck(s, str)
252 return s 252 return s
253 253
254 def Flush(self, ui, repo): 254 def Flush(self, ui, repo):
255 if self.name == "new": 255 if self.name == "new":
256 » » » self.Upload(ui, repo, gofmt_just_warn=True) 256 » » » self.Upload(ui, repo, gofmt_just_warn=True, creating=Tru e)
257 dir = CodeReviewDir(ui, repo) 257 dir = CodeReviewDir(ui, repo)
258 path = dir + '/cl.' + self.name 258 path = dir + '/cl.' + self.name
259 f = open(path+'!', "w") 259 f = open(path+'!', "w")
260 f.write(self.DiskText()) 260 f.write(self.DiskText())
261 f.close() 261 f.close()
262 if sys.platform == "win32" and os.path.isfile(path): 262 if sys.platform == "win32" and os.path.isfile(path):
263 os.remove(path) 263 os.remove(path)
264 os.rename(path+'!', path) 264 os.rename(path+'!', path)
265 if self.web and not self.copied_from: 265 if self.web and not self.copied_from:
266 EditDesc(self.name, desc=self.desc, 266 EditDesc(self.name, desc=self.desc,
267 reviewers=JoinComma(self.reviewer), cc=JoinComma (self.cc)) 267 reviewers=JoinComma(self.reviewer), cc=JoinComma (self.cc))
268 268
269 def Delete(self, ui, repo): 269 def Delete(self, ui, repo):
270 dir = CodeReviewDir(ui, repo) 270 dir = CodeReviewDir(ui, repo)
271 os.unlink(dir + "/cl." + self.name) 271 os.unlink(dir + "/cl." + self.name)
272 272
273 def Subject(self): 273 def Subject(self):
274 s = line1(self.desc) 274 s = line1(self.desc)
275 if len(s) > 60: 275 if len(s) > 60:
276 s = s[0:55] + "..." 276 s = s[0:55] + "..."
277 if self.name != "new": 277 if self.name != "new":
278 s = "code review %s: %s" % (self.name, s) 278 s = "code review %s: %s" % (self.name, s)
279 typecheck(s, str) 279 typecheck(s, str)
280 return s 280 return s
281 281
282 » def Upload(self, ui, repo, send_mail=False, gofmt=True, gofmt_just_warn= False): 282 » def Upload(self, ui, repo, send_mail=False, gofmt=True, gofmt_just_warn= False, creating=False, quiet=False):
283 » » if not self.files: 283 » » if not self.files and not creating:
284 ui.warn("no files in change list\n") 284 ui.warn("no files in change list\n")
285 if ui.configbool("codereview", "force_gofmt", True) and gofmt: 285 if ui.configbool("codereview", "force_gofmt", True) and gofmt:
286 CheckFormat(ui, repo, self.files, just_warn=gofmt_just_w arn) 286 CheckFormat(ui, repo, self.files, just_warn=gofmt_just_w arn)
287 set_status("uploading CL metadata + diffs") 287 set_status("uploading CL metadata + diffs")
288 os.chdir(repo.root) 288 os.chdir(repo.root)
289 form_fields = [ 289 form_fields = [
290 ("content_upload", "1"), 290 ("content_upload", "1"),
291 ("reviewers", JoinComma(self.reviewer)), 291 ("reviewers", JoinComma(self.reviewer)),
292 ("cc", JoinComma(self.cc)), 292 ("cc", JoinComma(self.cc)),
293 ("description", self.desc), 293 ("description", self.desc),
294 ("base_hashes", ""), 294 ("base_hashes", ""),
295 # Would prefer not to change the subject
296 # on reupload, but /upload requires it.
297 ("subject", self.Subject()),
298 ] 295 ]
299 296
300 if self.name != "new": 297 if self.name != "new":
301 form_fields.append(("issue", self.name)) 298 form_fields.append(("issue", self.name))
302 vcs = None 299 vcs = None
303 » » if self.files: 300 » » # We do not include files when creating the issue,
301 » » # because we want the patch sets to record the repository
302 » » # and base revision they are diffs against. We use the patch
303 » » # set message for that purpose, but there is no message with
304 » » # the first patch set. Instead the message gets used as the
305 » » # new CL's overall subject. So omit the diffs when creating
306 » » # and then we'll run an immediate upload.
307 » » # This has the effect that every CL begins with an empty "Patch set 1".
308 » » if self.files and not creating:
304 vcs = MercurialVCS(upload_options, ui, repo) 309 vcs = MercurialVCS(upload_options, ui, repo)
305 data = vcs.GenerateDiff(self.files) 310 data = vcs.GenerateDiff(self.files)
306 files = vcs.GetBaseFiles(data) 311 files = vcs.GetBaseFiles(data)
307 if len(data) > MAX_UPLOAD_SIZE: 312 if len(data) > MAX_UPLOAD_SIZE:
308 uploaded_diff_file = [] 313 uploaded_diff_file = []
309 form_fields.append(("separate_patches", "1")) 314 form_fields.append(("separate_patches", "1"))
310 else: 315 else:
311 uploaded_diff_file = [("data", "data.diff", data )] 316 uploaded_diff_file = [("data", "data.diff", data )]
312 else: 317 else:
313 uploaded_diff_file = [("data", "data.diff", emptydiff)] 318 uploaded_diff_file = [("data", "data.diff", emptydiff)]
319 ················
320 if vcs and self.name != "new":
321 form_fields.append(("subject", "diff -r " + vcs.base_rev + " " + getremote(ui, repo, {}).path))
322 else:
323 # First upload sets the subject for the CL itself.
324 form_fields.append(("subject", self.Subject()))
314 ctype, body = EncodeMultipartFormData(form_fields, uploaded_diff _file) 325 ctype, body = EncodeMultipartFormData(form_fields, uploaded_diff _file)
315 response_body = MySend("/upload", body, content_type=ctype) 326 response_body = MySend("/upload", body, content_type=ctype)
316 patchset = None 327 patchset = None
317 msg = response_body 328 msg = response_body
318 lines = msg.splitlines() 329 lines = msg.splitlines()
319 if len(lines) >= 2: 330 if len(lines) >= 2:
320 msg = lines[0] 331 msg = lines[0]
321 patchset = lines[1].strip() 332 patchset = lines[1].strip()
322 patches = [x.split(" ", 1) for x in lines[2:]] 333 patches = [x.split(" ", 1) for x in lines[2:]]
323 » » ui.status(msg + "\n") 334 » » if response_body.startswith("Issue updated.") and quiet:
335 » » » pass
336 » » else:
337 » » » ui.status(msg + "\n")
324 set_status("uploaded CL metadata + diffs") 338 set_status("uploaded CL metadata + diffs")
325 if not response_body.startswith("Issue created.") and not respon se_body.startswith("Issue updated."): 339 if not response_body.startswith("Issue created.") and not respon se_body.startswith("Issue updated."):
326 raise util.Abort("failed to update issue: " + response_b ody) 340 raise util.Abort("failed to update issue: " + response_b ody)
327 issue = msg[msg.rfind("/")+1:] 341 issue = msg[msg.rfind("/")+1:]
328 self.name = issue 342 self.name = issue
329 if not self.url: 343 if not self.url:
330 self.url = server_url_base + self.name 344 self.url = server_url_base + self.name
331 if not uploaded_diff_file: 345 if not uploaded_diff_file:
332 set_status("uploading patches") 346 set_status("uploading patches")
333 patches = UploadSeparatePatches(issue, rpc, patchset, da ta, upload_options) 347 patches = UploadSeparatePatches(issue, rpc, patchset, da ta, upload_options)
334 if vcs: 348 if vcs:
335 set_status("uploading base files") 349 set_status("uploading base files")
336 vcs.UploadBaseFiles(issue, rpc, patches, patchset, uploa d_options, files) 350 vcs.UploadBaseFiles(issue, rpc, patches, patchset, uploa d_options, files)
337 if send_mail: 351 if send_mail:
338 set_status("sending mail") 352 set_status("sending mail")
339 MySend("/" + issue + "/mail", payload="") 353 MySend("/" + issue + "/mail", payload="")
340 self.web = True 354 self.web = True
341 set_status("flushing changes to disk") 355 set_status("flushing changes to disk")
342 self.Flush(ui, repo) 356 self.Flush(ui, repo)
343 return 357 return
344 358
345 » def Mail(self, ui,repo): 359 » def Mail(self, ui, repo):
346 pmsg = "Hello " + JoinComma(self.reviewer) 360 pmsg = "Hello " + JoinComma(self.reviewer)
347 if self.cc: 361 if self.cc:
348 pmsg += " (cc: %s)" % (', '.join(self.cc),) 362 pmsg += " (cc: %s)" % (', '.join(self.cc),)
349 pmsg += ",\n" 363 pmsg += ",\n"
350 pmsg += "\n" 364 pmsg += "\n"
365 repourl = getremote(ui, repo, {}).path
351 if not self.mailed: 366 if not self.mailed:
352 » » » pmsg += "I'd like you to review this change.\n" 367 » » » pmsg += "I'd like you to review this change to\n" + repo url + "\n"
353 else: 368 else:
354 pmsg += "Please take another look.\n" 369 pmsg += "Please take another look.\n"
355 typecheck(pmsg, str) 370 typecheck(pmsg, str)
356 PostMessage(ui, self.name, pmsg, subject=self.Subject()) 371 PostMessage(ui, self.name, pmsg, subject=self.Subject())
357 self.mailed = True 372 self.mailed = True
358 self.Flush(ui, repo) 373 self.Flush(ui, repo)
359 374
360 def GoodCLName(name): 375 def GoodCLName(name):
361 typecheck(name, str) 376 typecheck(name, str)
362 return re.match("^[0-9]+$", name) 377 return re.match("^[0-9]+$", name)
(...skipping 712 matching lines...) Expand 10 before | Expand all | Expand 10 after
1075 1090
1076 if not opts["stdin"] and not opts["stdout"]: 1091 if not opts["stdin"] and not opts["stdout"]:
1077 if name == "new": 1092 if name == "new":
1078 cl.files = files 1093 cl.files = files
1079 err = EditCL(ui, repo, cl) 1094 err = EditCL(ui, repo, cl)
1080 if err != "": 1095 if err != "":
1081 return err 1096 return err
1082 dirty[cl] = True 1097 dirty[cl] = True
1083 1098
1084 for d, _ in dirty.items(): 1099 for d, _ in dirty.items():
1100 name = d.name
1085 d.Flush(ui, repo) 1101 d.Flush(ui, repo)
1102 if name == "new":
1103 d.Upload(ui, repo, quiet=True)
1086 1104
1087 if opts["stdout"]: 1105 if opts["stdout"]:
1088 ui.write(cl.EditorText()) 1106 ui.write(cl.EditorText())
1089 elif name == "new": 1107 elif name == "new":
1090 if ui.quiet: 1108 if ui.quiet:
1091 ui.write(cl.name) 1109 ui.write(cl.name)
1092 else: 1110 else:
1093 ui.write("CL created: " + cl.url + "\n") 1111 ui.write("CL created: " + cl.url + "\n")
1094 return 1112 return
1095 1113
(...skipping 25 matching lines...) Expand all
1121 argv = ["hgpatch"] 1139 argv = ["hgpatch"]
1122 if opts["no_incoming"]: 1140 if opts["no_incoming"]:
1123 argv += ["--checksync=false"] 1141 argv += ["--checksync=false"]
1124 if err != "": 1142 if err != "":
1125 return err 1143 return err
1126 try: 1144 try:
1127 cmd = subprocess.Popen(argv, shell=False, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=None, close_fds=sys.platform != "win32") 1145 cmd = subprocess.Popen(argv, shell=False, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=None, close_fds=sys.platform != "win32")
1128 except: 1146 except:
1129 return "hgpatch: " + ExceptionDetail() 1147 return "hgpatch: " + ExceptionDetail()
1130 1148
1131 » if sys.platform == "win32": 1149 » cmd.stdin.write(patch)
1132 » » cmd.stdin.write(patch)
1133 » » cmd.stdin.flush()
1134 » else:
1135 » » if os.fork() == 0:
1136 » » » cmd.stdin.write(patch)
1137 » » » os._exit(0)
1138 cmd.stdin.close() 1150 cmd.stdin.close()
1139 out = cmd.stdout.read() 1151 out = cmd.stdout.read()
1140 if cmd.wait() != 0 and not opts["ignore_hgpatch_failure"]: 1152 if cmd.wait() != 0 and not opts["ignore_hgpatch_failure"]:
1141 return "hgpatch failed" 1153 return "hgpatch failed"
1142 cl.local = True 1154 cl.local = True
1143 cl.files = out.strip().split() 1155 cl.files = out.strip().split()
1144 files = ChangedFiles(ui, repo, [], opts) 1156 files = ChangedFiles(ui, repo, [], opts)
1145 extra = Sub(cl.files, files) 1157 extra = Sub(cl.files, files)
1146 if extra: 1158 if extra:
1147 ui.warn("warning: these files were listed in the patch but not c hanged:\n\t" + "\n\t".join(extra) + "\n") 1159 ui.warn("warning: these files were listed in the patch but not c hanged:\n\t" + "\n\t".join(extra) + "\n")
(...skipping 1773 matching lines...) Expand 10 before | Expand all | Expand 10 after
2921 ctype, body = EncodeMultipartFormData(form_fields, files) 2933 ctype, body = EncodeMultipartFormData(form_fields, files)
2922 url = "/%d/upload_patch/%d" % (int(issue), int(patchset)) 2934 url = "/%d/upload_patch/%d" % (int(issue), int(patchset))
2923 print "Uploading patch for " + patch[0] 2935 print "Uploading patch for " + patch[0]
2924 response_body = rpc_server.Send(url, body, content_type=ctype) 2936 response_body = rpc_server.Send(url, body, content_type=ctype)
2925 lines = response_body.splitlines() 2937 lines = response_body.splitlines()
2926 if not lines or lines[0] != "OK": 2938 if not lines or lines[0] != "OK":
2927 StatusUpdate(" --> %s" % response_body) 2939 StatusUpdate(" --> %s" % response_body)
2928 sys.exit(1) 2940 sys.exit(1)
2929 rv.append([lines[1], patch[0]]) 2941 rv.append([lines[1], patch[0]])
2930 return rv 2942 return rv
LEFTRIGHT
« no previous file | no next file » | Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Toggle Comments ('s')

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b