OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # coding: utf-8 | 2 # coding: utf-8 |
3 # | 3 # |
4 # Copyright 2007 Google Inc. | 4 # Copyright 2007 Google Inc. |
5 # | 5 # |
6 # Licensed under the Apache License, Version 2.0 (the "License"); | 6 # Licensed under the Apache License, Version 2.0 (the "License"); |
7 # you may not use this file except in compliance with the License. | 7 # you may not use this file except in compliance with the License. |
8 # You may obtain a copy of the License at | 8 # You may obtain a copy of the License at |
9 # | 9 # |
10 # http://www.apache.org/licenses/LICENSE-2.0 | 10 # http://www.apache.org/licenses/LICENSE-2.0 |
(...skipping 1445 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1456 info = RunShell("hg log -r0 --template {node}".split()) | 1456 info = RunShell("hg log -r0 --template {node}".split()) |
1457 return info.strip() | 1457 return info.strip() |
1458 | 1458 |
1459 def _GetRelPath(self, filename): | 1459 def _GetRelPath(self, filename): |
1460 """Get relative path of a file according to the current directory, | 1460 """Get relative path of a file according to the current directory, |
1461 given its logical path in the repo.""" | 1461 given its logical path in the repo.""" |
1462 absname = os.path.join(self.repo_dir, filename) | 1462 absname = os.path.join(self.repo_dir, filename) |
1463 return os.path.relpath(absname) | 1463 return os.path.relpath(absname) |
1464 | 1464 |
1465 def GenerateDiff(self, extra_args): | 1465 def GenerateDiff(self, extra_args): |
1466 cmd = [ | 1466 cmd = ["hg", "diff", "--git", "-r", self.base_rev] + extra_args |
1467 "hg", "diff", "--color", "never", "--git", "-r", self.base_rev | |
1468 ] + extra_args | |
1469 data = RunShell(cmd, silent_ok=True) | 1467 data = RunShell(cmd, silent_ok=True) |
1470 svndiff = [] | 1468 svndiff = [] |
1471 filecount = 0 | 1469 filecount = 0 |
1472 for line in data.splitlines(): | 1470 for line in data.splitlines(): |
1473 m = re.match("diff --git a/(\S+) b/(\S+)", line) | 1471 m = re.match("diff --git a/(\S+) b/(\S+)", line) |
1474 if m: | 1472 if m: |
1475 # Modify line to make it look like as it comes from svn diff. | 1473 # Modify line to make it look like as it comes from svn diff. |
1476 # With this modification no changes on the server side are required | 1474 # With this modification no changes on the server side are required |
1477 # to make upload.py work with Mercurial repos. | 1475 # to make upload.py work with Mercurial repos. |
1478 # NOTE: for proper handling of moved/copied files, we have to use | 1476 # NOTE: for proper handling of moved/copied files, we have to use |
1479 # the second filename. | 1477 # the second filename. |
1480 filename = m.group(2) | 1478 filename = m.group(2) |
1481 svndiff.append("Index: %s" % filename) | 1479 svndiff.append("Index: %s" % filename) |
1482 svndiff.append("=" * 67) | 1480 svndiff.append("=" * 67) |
1483 filecount += 1 | 1481 filecount += 1 |
1484 logging.info(line) | 1482 logging.info(line) |
1485 else: | 1483 else: |
1486 svndiff.append(line) | 1484 svndiff.append(line) |
1487 if not filecount: | 1485 if not filecount: |
1488 ErrorExit("No valid patches found in output from hg diff") | 1486 ErrorExit("No valid patches found in output from hg diff") |
1489 return "\n".join(svndiff) + "\n" | 1487 return "\n".join(svndiff) + "\n" |
1490 | 1488 |
1491 def GetUnknownFiles(self): | 1489 def GetUnknownFiles(self): |
1492 """Return a list of files unknown to the VCS.""" | 1490 """Return a list of files unknown to the VCS.""" |
1493 args = [] | 1491 args = [] |
1494 status = RunShell( | 1492 status = RunShell(["hg", "status", "--rev", self.base_rev, "-u", "."], |
1495 ["hg", "status", "--color", "never", "--rev", self.base_rev, "-u", "."], | |
1496 silent_ok=True) | 1493 silent_ok=True) |
1497 unknown_files = [] | 1494 unknown_files = [] |
1498 for line in status.splitlines(): | 1495 for line in status.splitlines(): |
1499 st, fn = line.split(" ", 1) | 1496 st, fn = line.split(" ", 1) |
1500 if st == "?": | 1497 if st == "?": |
1501 unknown_files.append(fn) | 1498 unknown_files.append(fn) |
1502 return unknown_files | 1499 return unknown_files |
1503 | 1500 |
1504 def GetBaseFile(self, filename): | 1501 def GetBaseFile(self, filename): |
1505 # "hg status" and "hg cat" both take a path relative to the current subdir, | 1502 # "hg status" and "hg cat" both take a path relative to the current subdir, |
1506 # but "hg diff" has given us the path relative to the repo root. | 1503 # but "hg diff" has given us the path relative to the repo root. |
1507 base_content = "" | 1504 base_content = "" |
1508 new_content = None | 1505 new_content = None |
1509 is_binary = False | 1506 is_binary = False |
1510 oldrelpath = relpath = self._GetRelPath(filename) | 1507 oldrelpath = relpath = self._GetRelPath(filename) |
1511 # "hg status -C" returns two lines for moved/copied files, one otherwise | 1508 # "hg status -C" returns two lines for moved/copied files, one otherwise |
1512 out = RunShell( | 1509 out = RunShell(["hg", "status", "-C", "--rev", self.base_rev, relpath]) |
1513 [ "hg", "status", "--color", "never", "-C", "--rev", self.base_rev, | |
1514 relpath]) | |
1515 out = out.splitlines() | 1510 out = out.splitlines() |
1516 # HACK: strip error message about missing file/directory if it isn't in | 1511 # HACK: strip error message about missing file/directory if it isn't in |
1517 # the working copy | 1512 # the working copy |
1518 if out[0].startswith('%s: ' % relpath): | 1513 if out[0].startswith('%s: ' % relpath): |
1519 out = out[1:] | 1514 out = out[1:] |
1520 status, _ = out[0].split(' ', 1) | 1515 status, _ = out[0].split(' ', 1) |
1521 if len(out) > 1 and status == "A": | 1516 if len(out) > 1 and status == "A": |
1522 # Moved/copied => considered as modified, use old filename to | 1517 # Moved/copied => considered as modified, use old filename to |
1523 # retrieve base contents | 1518 # retrieve base contents |
1524 oldrelpath = out[1].strip() | 1519 oldrelpath = out[1].strip() |
(...skipping 745 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2270 ErrorExit("A non-empty title is required for a new issue") | 2265 ErrorExit("A non-empty title is required for a new issue") |
2271 # For existing issues, it's fine to give a patchset an empty name. Rietveld | 2266 # For existing issues, it's fine to give a patchset an empty name. Rietveld |
2272 # doesn't accept that so use a whitespace. | 2267 # doesn't accept that so use a whitespace. |
2273 title = title or " " | 2268 title = title or " " |
2274 if len(title) > 100: | 2269 if len(title) > 100: |
2275 title = title[:99] + '…' | 2270 title = title[:99] + '…' |
2276 if title and not options.issue: | 2271 if title and not options.issue: |
2277 message = message or title | 2272 message = message or title |
2278 | 2273 |
2279 form_fields.append(("subject", title)) | 2274 form_fields.append(("subject", title)) |
2280 if message: | 2275 # If it's a new issue send message as description. Otherwise a new |
2281 if not options.issue: | 2276 # message is created below on upload_complete. |
2282 form_fields.append(("description", message)) | 2277 if message and not options.issue: |
2283 else: | 2278 form_fields.append(("description", message)) |
2284 # TODO: [ ] Use /<issue>/publish to add a comment. | |
2285 pass | |
2286 | 2279 |
2287 # Send a hash of all the base file so the server can determine if a copy | 2280 # Send a hash of all the base file so the server can determine if a copy |
2288 # already exists in an earlier patchset. | 2281 # already exists in an earlier patchset. |
2289 base_hashes = "" | 2282 base_hashes = "" |
2290 for file, info in files.iteritems(): | 2283 for file, info in files.iteritems(): |
2291 if not info[0] is None: | 2284 if not info[0] is None: |
2292 checksum = md5(info[0]).hexdigest() | 2285 checksum = md5(info[0]).hexdigest() |
2293 if base_hashes: | 2286 if base_hashes: |
2294 base_hashes += "|" | 2287 base_hashes += "|" |
2295 base_hashes += checksum + ":" + file | 2288 base_hashes += checksum + ":" + file |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2334 patches = result | 2327 patches = result |
2335 | 2328 |
2336 if not options.download_base: | 2329 if not options.download_base: |
2337 vcs.UploadBaseFiles(issue, rpc_server, patches, patchset, options, files) | 2330 vcs.UploadBaseFiles(issue, rpc_server, patches, patchset, options, files) |
2338 | 2331 |
2339 payload = {} # payload for final request | 2332 payload = {} # payload for final request |
2340 if options.send_mail: | 2333 if options.send_mail: |
2341 payload["send_mail"] = "yes" | 2334 payload["send_mail"] = "yes" |
2342 if options.send_patch: | 2335 if options.send_patch: |
2343 payload["attach_patch"] = "yes" | 2336 payload["attach_patch"] = "yes" |
| 2337 if options.issue and message: |
| 2338 payload["message"] = message |
2344 payload = urllib.urlencode(payload) | 2339 payload = urllib.urlencode(payload) |
2345 rpc_server.Send("/" + issue + "/upload_complete/" + (patchset or ""), | 2340 rpc_server.Send("/" + issue + "/upload_complete/" + (patchset or ""), |
2346 payload=payload) | 2341 payload=payload) |
2347 return issue, patchset | 2342 return issue, patchset |
2348 | 2343 |
2349 | 2344 |
2350 def main(): | 2345 def main(): |
2351 try: | 2346 try: |
2352 logging.basicConfig(format=("%(asctime).19s %(levelname)s %(filename)s:" | 2347 logging.basicConfig(format=("%(asctime).19s %(levelname)s %(filename)s:" |
2353 "%(lineno)s %(message)s ")) | 2348 "%(lineno)s %(message)s ")) |
2354 os.environ['LC_ALL'] = 'C' | 2349 os.environ['LC_ALL'] = 'C' |
2355 RealMain(sys.argv) | 2350 RealMain(sys.argv) |
2356 except KeyboardInterrupt: | 2351 except KeyboardInterrupt: |
2357 print | 2352 print |
2358 StatusUpdate("Interrupted.") | 2353 StatusUpdate("Interrupted.") |
2359 sys.exit(1) | 2354 sys.exit(1) |
2360 | 2355 |
2361 | 2356 |
2362 if __name__ == "__main__": | 2357 if __name__ == "__main__": |
2363 main() | 2358 main() |
OLD | NEW |