Left: | ||
Right: |
OLD | NEW |
---|---|
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # | 2 # |
3 # Copyright 2007 Google Inc. | 3 # Copyright 2007 Google Inc. |
4 # | 4 # |
5 # Licensed under the Apache License, Version 2.0 (the "License"); | 5 # Licensed under the Apache License, Version 2.0 (the "License"); |
6 # you may not use this file except in compliance with the License. | 6 # you may not use this file except in compliance with the License. |
7 # You may obtain a copy of the License at | 7 # You may obtain a copy of the License at |
8 # | 8 # |
9 # http://www.apache.org/licenses/LICENSE-2.0 | 9 # http://www.apache.org/licenses/LICENSE-2.0 |
10 # | 10 # |
(...skipping 447 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
458 def GetContentType(filename): | 458 def GetContentType(filename): |
459 """Helper to guess the content-type from the filename.""" | 459 """Helper to guess the content-type from the filename.""" |
460 return mimetypes.guess_type(filename)[0] or 'application/octet-stream' | 460 return mimetypes.guess_type(filename)[0] or 'application/octet-stream' |
461 | 461 |
462 | 462 |
463 def RunShell(command, args=(), silent_ok=False): | 463 def RunShell(command, args=(), silent_ok=False): |
464 command = "%s %s" % (command, " ".join(args)) | 464 command = "%s %s" % (command, " ".join(args)) |
465 logging.info("Running %s", command) | 465 logging.info("Running %s", command) |
466 stream = os.popen(command, "r") | 466 stream = os.popen(command, "r") |
467 data = stream.read() | 467 data = stream.read() |
468 if stream.close(): | 468 status = stream.close() |
469 ErrorExit("Got error status from %s" % command) | 469 logging.info(status) |
470 if status: | |
471 ErrorExit("Got error status %s from %s" % (status,command)) | |
470 if not silent_ok and not data: | 472 if not silent_ok and not data: |
471 ErrorExit("No output from %s" % command) | 473 ErrorExit("No output from %s" % command) |
472 return data | 474 return data |
473 | 475 |
474 | 476 |
475 def GuessBase(): | 477 def GuessBase(allow_other=False): |
476 info = RunShell("svn info") | 478 info = RunShell("svn info") |
477 for line in info.splitlines(): | 479 for line in info.splitlines(): |
478 words = line.split() | 480 words = line.split() |
479 if len(words) == 2 and words[0] == "URL:": | 481 if len(words) == 2 and words[0] == "URL:": |
480 url = words[1] | 482 url = words[1] |
481 scheme, netloc, path, params, query, fragment = urlparse.urlparse(url) | 483 scheme, netloc, path, params, query, fragment = urlparse.urlparse(url) |
482 if netloc.endswith("svn.python.org"): | 484 if netloc.endswith("svn.python.org"): |
483 if netloc == "svn.python.org": | 485 if netloc == "svn.python.org": |
484 if path.startswith("/projects/"): | 486 if path.startswith("/projects/"): |
485 path = path[9:] | 487 path = path[9:] |
486 elif netloc != "pythondev@svn.python.org": | 488 elif netloc != "pythondev@svn.python.org": |
487 ErrorExit("Unrecognized Python URL: %s" % url) | 489 ErrorExit("Unrecognized Python URL: %s" % url) |
488 base = "http://svn.python.org/view/*checkout*%s/" % path | 490 base = "http://svn.python.org/view/*checkout*%s/" % path |
489 logging.info("Guessed Python base = %s", base) | 491 logging.info("Guessed Python base = %s", base) |
490 elif netloc.endswith("svn.collab.net"): | 492 elif netloc.endswith("svn.collab.net"): |
491 if path.startswith("/repos/"): | 493 if path.startswith("/repos/"): |
492 path = path[6:] | 494 path = path[6:] |
493 base = "http://svn.collab.net/viewvc/*checkout*%s/" % path | 495 base = "http://svn.collab.net/viewvc/*checkout*%s/" % path |
494 logging.info("Guessed CollabNet base = %s", base) | 496 logging.info("Guessed CollabNet base = %s", base) |
495 elif netloc.endswith(".googlecode.com"): | 497 elif netloc.endswith(".googlecode.com"): |
496 base = url + "/" | 498 base = url + "/" |
497 if base.startswith("https"): | 499 if base.startswith("https"): |
498 base = "http" + base[5:] | 500 base = "http" + base[5:] |
499 logging.info("Guessed Google Code base = %s", base) | 501 logging.info("Guessed Google Code base = %s", base) |
502 elif allow_other: | |
503 return url | |
500 else: | 504 else: |
501 ErrorExit("Unrecognized svn project root: %s" % url) | 505 ErrorExit("Unrecognized svn project root: %s" % url) |
502 return base | 506 return base |
503 ErrorExit("Can't find URL in output from svn info") | 507 ErrorExit("Can't find URL in output from svn info") |
504 | 508 |
505 | 509 |
506 def RealMain(argv): | 510 def RealMain(argv): |
507 logging.basicConfig(format=("%(asctime).19s %(levelname)s %(filename)s:" | 511 logging.basicConfig(format=("%(asctime).19s %(levelname)s %(filename)s:" |
508 "%(lineno)s %(message)s ")) | 512 "%(lineno)s %(message)s ")) |
509 os.environ['LC_ALL'] = 'C' | 513 os.environ['LC_ALL'] = 'C' |
510 options, args = parser.parse_args(sys.argv[1:]) | 514 options, args = parser.parse_args(sys.argv[1:]) |
511 global verbosity | 515 global verbosity |
512 verbosity = options.verbose | 516 verbosity = options.verbose |
513 if verbosity >= 3: | 517 if verbosity >= 3: |
514 logging.getLogger().setLevel(logging.DEBUG) | 518 logging.getLogger().setLevel(logging.DEBUG) |
515 elif verbosity >= 2: | 519 elif verbosity >= 2: |
516 logging.getLogger().setLevel(logging.INFO) | 520 logging.getLogger().setLevel(logging.INFO) |
517 if options.local_base: | 521 if options.local_base: |
518 base = None | 522 base = GuessBase(allow_other=True) |
519 else: | 523 else: |
520 base = GuessBase() | 524 base = GuessBase() |
521 if not options.assume_yes: | 525 if not options.assume_yes: |
522 CheckForUnknownFiles() | 526 CheckForUnknownFiles() |
523 cmd = "svn diff" | 527 cmd = "svn diff" |
524 if not sys.platform.startswith("win"): | 528 if not sys.platform.startswith("win"): |
525 cmd += " --diff-cmd=diff" | 529 cmd += " --diff-cmd=diff" |
526 data = RunShell(cmd, args) | 530 data = RunShell(cmd, args) |
527 count = 0 | 531 count = 0 |
532 revisions = dict() | |
528 for line in data.splitlines(): | 533 for line in data.splitlines(): |
529 if line.startswith("Index:"): | 534 if line.startswith("Index:"): |
530 count += 1 | 535 count += 1 |
531 logging.info(line) | 536 logging.info(line) |
537 if line.startswith("--"): | |
538 file = line.split(" ",1)[1].split("\t",1)[0] | |
539 revision = line[line.rfind("(revision ")+10:].replace(")","") | |
540 revisions[file] = revision | |
Janusz 2008/07/28 21:13:21 I'm sure ther is better way to do this. I'm new to | |
532 if not count: | 541 if not count: |
533 ErrorExit("No valid patches found in output from svn diff") | 542 ErrorExit("No valid patches found in output from svn diff") |
534 if options.issue: | 543 if options.issue: |
535 prompt = "Message describing this patch set: " | 544 prompt = "Message describing this patch set: " |
536 else: | 545 else: |
537 prompt = "New issue subject: " | 546 prompt = "New issue subject: " |
538 message = options.message or raw_input(prompt).strip() | 547 message = options.message or raw_input(prompt).strip() |
539 if not message: | 548 if not message: |
540 ErrorExit("A non-empty message is required") | 549 ErrorExit("A non-empty message is required") |
541 rpc_server = GetRpcServer(options) | 550 rpc_server = GetRpcServer(options) |
(...skipping 28 matching lines...) Expand all Loading... | |
570 else: | 579 else: |
571 msg = response_body | 580 msg = response_body |
572 else: | 581 else: |
573 msg = response_body | 582 msg = response_body |
574 StatusUpdate(msg) | 583 StatusUpdate(msg) |
575 if not response_body.startswith("Issue created.") and \ | 584 if not response_body.startswith("Issue created.") and \ |
576 not response_body.startswith("Issue updated."): | 585 not response_body.startswith("Issue updated."): |
577 sys.exit(0) | 586 sys.exit(0) |
578 if options.local_base: | 587 if options.local_base: |
579 issue = msg[msg.rfind("/")+1:] | 588 issue = msg[msg.rfind("/")+1:] |
580 UploadBaseFiles(issue, rpc_server, patches, patchset, options) | 589 UploadBaseFiles(issue, rpc_server, patches, patchset, options, base, revisions ) |
581 | 590 |
582 def UploadBaseFiles(issue, rpc_server, patch_list, patchset, options): | 591 def UploadBaseFiles(issue, rpc_server, patch_list, patchset, options, base, revi sions): |
583 """Uploads the base files using svn cat.""" | 592 """Uploads the base files using svn cat.""" |
584 patches = dict() | 593 patches = dict() |
585 [patches.setdefault(v, k) for k, v in patch_list] | 594 [patches.setdefault(v, k) for k, v in patch_list] |
586 for filename in patches.keys(): | 595 for filename in patches.keys(): |
587 status = RunShell("svn status --ignore-externals", [filename]) | 596 status = RunShell("svn status --ignore-externals", [filename], silent_ok=Tru e) |
597 use_revision = False | |
Janusz 2008/07/28 21:13:21 used, will purge | |
588 if not status: | 598 if not status: |
589 StatusUpdate("svn status returned no output for %s" % filename) | 599 StatusUpdate("svn status returned no output for %s" % filename) |
590 sys.exit(False) | 600 status = "^" |
591 if status[0] == "A": | 601 if status and status[0] == "A": |
592 content = "" | 602 content = "" |
593 elif status[0] in ["M", "D"]: | 603 elif status and (status[0] in ["M", "D", "^"]): |
594 content = RunShell("svn cat", [filename]) | 604 file_url = str(base)+"/"+filename+"@"+str(revisions[filename]) |
595 keywords = RunShell("svn -rBASE propget svn:keywords", [filename], | 605 content = RunShell("svn cat", [file_url]) |
596 silent_ok=True) | 606 keywords = RunShell("svn propget svn:keywords", [file_url], silent_ok=True ) |
597 if keywords: | 607 if keywords: |
598 content = CollapseKeywords(content, keywords) | 608 content = CollapseKeywords(content, keywords)» |
599 else: | 609 else: |
600 StatusUpdate("svn status returned unexpected output: %s" % status) | 610 StatusUpdate("svn status returned unexpected output: %s" % status) |
601 sys.exit(False) | 611 sys.exit(False) |
602 checksum = md5.new(content).hexdigest() | 612 checksum = md5.new(content).hexdigest() |
603 parts = [] | 613 parts = [] |
604 while content: | 614 while content: |
605 parts.append(content[:800000]) | 615 parts.append(content[:800000]) |
606 content = content[800000:] | 616 content = content[800000:] |
607 if not parts: | 617 if not parts: |
608 parts = [""] # empty file | 618 parts = [""] # empty file |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
676 try: | 686 try: |
677 RealMain(sys.argv) | 687 RealMain(sys.argv) |
678 except KeyboardInterrupt: | 688 except KeyboardInterrupt: |
679 print | 689 print |
680 StatusUpdate("Interrupted.") | 690 StatusUpdate("Interrupted.") |
681 sys.exit(1) | 691 sys.exit(1) |
682 | 692 |
683 | 693 |
684 if __name__ == "__main__": | 694 if __name__ == "__main__": |
685 main() | 695 main() |
OLD | NEW |