OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env 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 # Copyright (C) 2008 Evan Martin <martine@danga.com> | 6 # Copyright (C) 2008 Evan Martin <martine@danga.com> |
7 | 7 |
8 """A git-command for integrating reviews on Rietveld.""" | 8 """A git-command for integrating reviews on Rietveld.""" |
9 | 9 |
10 import errno | 10 import errno |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
49 DESCRIPTION_BACKUP_FILE = '~/.git_cl_description_backup' | 49 DESCRIPTION_BACKUP_FILE = '~/.git_cl_description_backup' |
50 | 50 |
51 | 51 |
52 def DieWithError(message): | 52 def DieWithError(message): |
53 print >> sys.stderr, message | 53 print >> sys.stderr, message |
54 sys.exit(1) | 54 sys.exit(1) |
55 | 55 |
56 | 56 |
57 def Popen(cmd, **kwargs): | 57 def Popen(cmd, **kwargs): |
58 """Wrapper for subprocess.Popen() that logs and watch for cygwin issues""" | 58 """Wrapper for subprocess.Popen() that logs and watch for cygwin issues""" |
59 logging.info('Popen: ' + ' '.join(cmd)) | 59 logging.debug('Popen: ' + ' '.join(cmd)) |
60 try: | 60 try: |
61 return subprocess.Popen(cmd, **kwargs) | 61 return subprocess.Popen(cmd, **kwargs) |
62 except OSError, e: | 62 except OSError, e: |
63 if e.errno == errno.EAGAIN and sys.platform == 'cygwin': | 63 if e.errno == errno.EAGAIN and sys.platform == 'cygwin': |
64 DieWithError( | 64 DieWithError( |
65 'Visit ' | 65 'Visit ' |
66 'http://code.google.com/p/chromium/wiki/CygwinDllRemappingFailure to ' | 66 'http://code.google.com/p/chromium/wiki/CygwinDllRemappingFailure to ' |
67 'learn how to fix this error; you need to rebase your cygwin dlls') | 67 'learn how to fix this error; you need to rebase your cygwin dlls') |
68 raise | 68 raise |
69 | 69 |
(...skipping 733 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
803 | 803 |
804 | 804 |
805 def ConvertToInteger(inputval): | 805 def ConvertToInteger(inputval): |
806 """Convert a string to integer, but returns either an int or None.""" | 806 """Convert a string to integer, but returns either an int or None.""" |
807 try: | 807 try: |
808 return int(inputval) | 808 return int(inputval) |
809 except (TypeError, ValueError): | 809 except (TypeError, ValueError): |
810 return None | 810 return None |
811 | 811 |
812 | 812 |
813 def RunHook(committing, upstream_branch, rietveld_server, tbr, may_prompt): | 813 def RunHook(committing, upstream_branch, rietveld_server, tbr, may_prompt, |
| 814 verbose): |
814 """Calls sys.exit() if the hook fails; returns a HookResults otherwise.""" | 815 """Calls sys.exit() if the hook fails; returns a HookResults otherwise.""" |
815 root = RunCommand(['git', 'rev-parse', '--show-cdup']).strip() | 816 root = RunCommand(['git', 'rev-parse', '--show-cdup']).strip() |
816 if not root: | 817 if not root: |
817 root = '.' | 818 root = '.' |
818 absroot = os.path.abspath(root) | 819 absroot = os.path.abspath(root) |
819 if not root: | 820 if not root: |
820 raise Exception('Could not get root directory.') | 821 raise Exception('Could not get root directory.') |
821 | 822 |
822 # We use the sha1 of HEAD as a name of this change. | 823 # We use the sha1 of HEAD as a name of this change. |
823 name = RunCommand(['git', 'rev-parse', 'HEAD']).strip() | 824 name = RunCommand(['git', 'rev-parse', 'HEAD']).strip() |
(...skipping 12 matching lines...) Expand all Loading... |
836 '%s...' % (upstream_branch)]).strip() | 837 '%s...' % (upstream_branch)]).strip() |
837 change = presubmit_support.GitChange(name, description, absroot, files, | 838 change = presubmit_support.GitChange(name, description, absroot, files, |
838 issue, patchset) | 839 issue, patchset) |
839 | 840 |
840 # Apply watchlists on upload. | 841 # Apply watchlists on upload. |
841 if not committing: | 842 if not committing: |
842 watchlist = watchlists.Watchlists(change.RepositoryRoot()) | 843 watchlist = watchlists.Watchlists(change.RepositoryRoot()) |
843 files = [f.LocalPath() for f in change.AffectedFiles()] | 844 files = [f.LocalPath() for f in change.AffectedFiles()] |
844 cl.SetWatchers(watchlist.GetWatchersForPaths(files)) | 845 cl.SetWatchers(watchlist.GetWatchersForPaths(files)) |
845 | 846 |
846 output = presubmit_support.DoPresubmitChecks(change, committing, | 847 try: |
847 verbose=False, output_stream=sys.stdout, input_stream=sys.stdin, | 848 output = presubmit_support.DoPresubmitChecks(change, committing, |
848 default_presubmit=None, may_prompt=may_prompt, tbr=tbr, | 849 verbose=verbose, output_stream=sys.stdout, input_stream=sys.stdin, |
849 host_url=cl.GetRietveldServer()) | 850 default_presubmit=None, may_prompt=may_prompt, tbr=tbr, |
| 851 host_url=cl.GetRietveldServer()) |
| 852 except presubmit_support.PresubmitFailure, e: |
| 853 DieWithError( |
| 854 ('%s\nMaybe your depot_tools is out of date?\n' |
| 855 'If all fails, contact maruel@') % e) |
850 | 856 |
851 # TODO(dpranke): We should propagate the error out instead of calling exit(). | 857 # TODO(dpranke): We should propagate the error out instead of calling exit(). |
852 if not output.should_continue(): | 858 if not output.should_continue(): |
853 sys.exit(1) | 859 sys.exit(1) |
854 | 860 |
855 return output | 861 return output |
856 | 862 |
857 | 863 |
858 def CMDpresubmit(parser, args): | 864 def CMDpresubmit(parser, args): |
859 """run presubmit tests on the current changelist""" | 865 """run presubmit tests on the current changelist""" |
(...skipping 10 matching lines...) Expand all Loading... |
870 | 876 |
871 cl = Changelist() | 877 cl = Changelist() |
872 if args: | 878 if args: |
873 base_branch = args[0] | 879 base_branch = args[0] |
874 else: | 880 else: |
875 # Default to diffing against the "upstream" branch. | 881 # Default to diffing against the "upstream" branch. |
876 base_branch = cl.GetUpstreamBranch() | 882 base_branch = cl.GetUpstreamBranch() |
877 | 883 |
878 RunHook(committing=not options.upload, upstream_branch=base_branch, | 884 RunHook(committing=not options.upload, upstream_branch=base_branch, |
879 rietveld_server=cl.GetRietveldServer(), tbr=False, | 885 rietveld_server=cl.GetRietveldServer(), tbr=False, |
880 may_prompt=False) | 886 may_prompt=False, verbose=options.verbose) |
881 return 0 | 887 return 0 |
882 | 888 |
883 | 889 |
884 @usage('[args to "git diff"]') | 890 @usage('[args to "git diff"]') |
885 def CMDupload(parser, args): | 891 def CMDupload(parser, args): |
886 """upload the current changelist to codereview""" | 892 """upload the current changelist to codereview""" |
887 parser.add_option('--bypass-hooks', action='store_true', dest='bypass_hooks', | 893 parser.add_option('--bypass-hooks', action='store_true', dest='bypass_hooks', |
888 help='bypass upload presubmit hook') | 894 help='bypass upload presubmit hook') |
889 parser.add_option('-f', action='store_true', dest='force', | 895 parser.add_option('-f', action='store_true', dest='force', |
890 help="force yes to questions (don't prompt)") | 896 help="force yes to questions (don't prompt)") |
(...skipping 23 matching lines...) Expand all Loading... |
914 if args: | 920 if args: |
915 base_branch = args[0] | 921 base_branch = args[0] |
916 else: | 922 else: |
917 # Default to diffing against the "upstream" branch. | 923 # Default to diffing against the "upstream" branch. |
918 base_branch = cl.GetUpstreamBranch() | 924 base_branch = cl.GetUpstreamBranch() |
919 args = [base_branch + "..."] | 925 args = [base_branch + "..."] |
920 | 926 |
921 if not options.bypass_hooks and not options.force: | 927 if not options.bypass_hooks and not options.force: |
922 hook_results = RunHook(committing=False, upstream_branch=base_branch, | 928 hook_results = RunHook(committing=False, upstream_branch=base_branch, |
923 rietveld_server=cl.GetRietveldServer(), tbr=False, | 929 rietveld_server=cl.GetRietveldServer(), tbr=False, |
924 may_prompt=True) | 930 may_prompt=True, verbose=options.verbose) |
925 if not options.reviewers and hook_results.reviewers: | 931 if not options.reviewers and hook_results.reviewers: |
926 options.reviewers = hook_results.reviewers | 932 options.reviewers = hook_results.reviewers |
927 | 933 |
928 | 934 |
929 # --no-ext-diff is broken in some versions of Git, so try to work around | 935 # --no-ext-diff is broken in some versions of Git, so try to work around |
930 # this by overriding the environment (but there is still a problem if the | 936 # this by overriding the environment (but there is still a problem if the |
931 # git config key "diff.external" is used). | 937 # git config key "diff.external" is used). |
932 env = os.environ.copy() | 938 env = os.environ.copy() |
933 if 'GIT_EXTERNAL_DIFF' in env: | 939 if 'GIT_EXTERNAL_DIFF' in env: |
934 del env['GIT_EXTERNAL_DIFF'] | 940 del env['GIT_EXTERNAL_DIFF'] |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1067 if extra_commits: | 1073 if extra_commits: |
1068 print ('This branch has %d additional commits not upstreamed yet.' | 1074 print ('This branch has %d additional commits not upstreamed yet.' |
1069 % len(extra_commits.splitlines())) | 1075 % len(extra_commits.splitlines())) |
1070 print ('Upstream "%s" or rebase this branch on top of the upstream trunk ' | 1076 print ('Upstream "%s" or rebase this branch on top of the upstream trunk ' |
1071 'before attempting to %s.' % (base_branch, cmd)) | 1077 'before attempting to %s.' % (base_branch, cmd)) |
1072 return 1 | 1078 return 1 |
1073 | 1079 |
1074 if not options.bypass_hooks and not options.force: | 1080 if not options.bypass_hooks and not options.force: |
1075 RunHook(committing=True, upstream_branch=base_branch, | 1081 RunHook(committing=True, upstream_branch=base_branch, |
1076 rietveld_server=cl.GetRietveldServer(), tbr=options.tbr, | 1082 rietveld_server=cl.GetRietveldServer(), tbr=options.tbr, |
1077 may_prompt=True) | 1083 may_prompt=True, verbose=options.verbose) |
1078 | 1084 |
1079 if cmd == 'dcommit': | 1085 if cmd == 'dcommit': |
1080 # Check the tree status if the tree status URL is set. | 1086 # Check the tree status if the tree status URL is set. |
1081 status = GetTreeStatus() | 1087 status = GetTreeStatus() |
1082 if 'closed' == status: | 1088 if 'closed' == status: |
1083 print ('The tree is closed. Please wait for it to reopen. Use ' | 1089 print ('The tree is closed. Please wait for it to reopen. Use ' |
1084 '"git cl dcommit -f" to commit on a closed tree.') | 1090 '"git cl dcommit -f" to commit on a closed tree.') |
1085 return 1 | 1091 return 1 |
1086 elif 'unknown' == status: | 1092 elif 'unknown' == status: |
1087 print ('Unable to determine tree status. Please verify manually and ' | 1093 print ('Unable to determine tree status. Please verify manually and ' |
(...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1400 def main(argv): | 1406 def main(argv): |
1401 """Doesn't parse the arguments here, just find the right subcommand to | 1407 """Doesn't parse the arguments here, just find the right subcommand to |
1402 execute.""" | 1408 execute.""" |
1403 # Do it late so all commands are listed. | 1409 # Do it late so all commands are listed. |
1404 CMDhelp.usage_more = ('\n\nCommands are:\n' + '\n'.join([ | 1410 CMDhelp.usage_more = ('\n\nCommands are:\n' + '\n'.join([ |
1405 ' %-10s %s' % (fn[3:], Command(fn[3:]).__doc__.split('\n')[0].strip()) | 1411 ' %-10s %s' % (fn[3:], Command(fn[3:]).__doc__.split('\n')[0].strip()) |
1406 for fn in dir(sys.modules[__name__]) if fn.startswith('CMD')])) | 1412 for fn in dir(sys.modules[__name__]) if fn.startswith('CMD')])) |
1407 | 1413 |
1408 # Create the option parse and add --verbose support. | 1414 # Create the option parse and add --verbose support. |
1409 parser = optparse.OptionParser() | 1415 parser = optparse.OptionParser() |
1410 parser.add_option('-v', '--verbose', action='store_true') | 1416 parser.add_option( |
| 1417 '-v', '--verbose', action='count', default=0, |
| 1418 help='Use 2 times for more debugging info') |
1411 old_parser_args = parser.parse_args | 1419 old_parser_args = parser.parse_args |
1412 def Parse(args): | 1420 def Parse(args): |
1413 options, args = old_parser_args(args) | 1421 options, args = old_parser_args(args) |
1414 if options.verbose: | 1422 if options.verbose >= 2: |
1415 logging.basicConfig(level=logging.DEBUG) | 1423 logging.basicConfig(level=logging.DEBUG) |
| 1424 elif options.verbose: |
| 1425 logging.basicConfig(level=logging.INFO) |
1416 else: | 1426 else: |
1417 logging.basicConfig(level=logging.WARNING) | 1427 logging.basicConfig(level=logging.WARNING) |
1418 return options, args | 1428 return options, args |
1419 parser.parse_args = Parse | 1429 parser.parse_args = Parse |
1420 | 1430 |
1421 if argv: | 1431 if argv: |
1422 command = Command(argv[0]) | 1432 command = Command(argv[0]) |
1423 if command: | 1433 if command: |
1424 # "fix" the usage and the description now that we know the subcommand. | 1434 # "fix" the usage and the description now that we know the subcommand. |
1425 GenUsage(parser, argv[0]) | 1435 GenUsage(parser, argv[0]) |
1426 try: | 1436 try: |
1427 return command(parser, argv[1:]) | 1437 return command(parser, argv[1:]) |
1428 except urllib2.HTTPError, e: | 1438 except urllib2.HTTPError, e: |
1429 if e.code != 500: | 1439 if e.code != 500: |
1430 raise | 1440 raise |
1431 DieWithError( | 1441 DieWithError( |
1432 ('AppEngine is misbehaving and returned HTTP %d, again. Keep faith ' | 1442 ('AppEngine is misbehaving and returned HTTP %d, again. Keep faith ' |
1433 'and retry or visit go/isgaeup.\n%s') % (e.code, str(e))) | 1443 'and retry or visit go/isgaeup.\n%s') % (e.code, str(e))) |
1434 | 1444 |
1435 # Not a known command. Default to help. | 1445 # Not a known command. Default to help. |
1436 GenUsage(parser, 'help') | 1446 GenUsage(parser, 'help') |
1437 return CMDhelp(parser, argv) | 1447 return CMDhelp(parser, argv) |
1438 | 1448 |
1439 | 1449 |
1440 if __name__ == '__main__': | 1450 if __name__ == '__main__': |
1441 fix_encoding.fix_encoding() | 1451 fix_encoding.fix_encoding() |
1442 sys.exit(main(sys.argv[1:])) | 1452 sys.exit(main(sys.argv[1:])) |
OLD | NEW |