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

Side by Side Diff: git_cl/git_cl.py

Issue 6665018: Remove support for generic "hook files" in git-cl, require depot_tools (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/depot_tools
Patch Set: put dcommit hook back in Created 9 years, 9 months 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | git_cl/test/hooks.sh » ('j') | 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 # git-cl -- a git-command for integrating reviews on Rietveld 2 # git-cl -- a git-command for integrating reviews on Rietveld
3 # Copyright (C) 2008 Evan Martin <martine@danga.com> 3 # Copyright (C) 2008 Evan Martin <martine@danga.com>
4 4
5 import errno 5 import errno
6 import logging 6 import logging
7 import optparse 7 import optparse
8 import os 8 import os
9 import re 9 import re
10 import subprocess 10 import subprocess
11 import sys 11 import sys
12 import tempfile 12 import tempfile
13 import textwrap 13 import textwrap
14 import upload 14 import upload
15 import urlparse 15 import urlparse
16 import urllib2 16 import urllib2
17 17
18 try: 18 try:
19 import readline 19 import readline
20 except ImportError: 20 except ImportError:
21 pass 21 pass
22 22
23 try: 23 try:
24 # Add the parent directory in case it's a depot_tools checkout. 24 # TODO(dpranke): We wrap this in a try block for a limited form of
25 # backwards-compatibility with older versions of git-cl that weren't
26 # dependent on depot_tools. This version should still work outside of
27 # depot_tools as long as --bypass-hooks is used. We should remove this
28 # once this has baked for a while and things seem safe.
25 depot_tools_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 29 depot_tools_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
26 sys.path.append(depot_tools_path) 30 sys.path.append(depot_tools_path)
27 import breakpad 31 import breakpad
28 except ImportError: 32 except ImportError:
29 pass 33 pass
30 34
31 DEFAULT_SERVER = 'http://codereview.appspot.com' 35 DEFAULT_SERVER = 'http://codereview.appspot.com'
32 PREDCOMMIT_HOOK = '.git/hooks/pre-cl-dcommit'
33 POSTUPSTREAM_HOOK_PATTERN = '.git/hooks/post-cl-%s' 36 POSTUPSTREAM_HOOK_PATTERN = '.git/hooks/post-cl-%s'
34 PREUPLOAD_HOOK = '.git/hooks/pre-cl-upload'
35 DESCRIPTION_BACKUP_FILE = '~/.git_cl_description_backup' 37 DESCRIPTION_BACKUP_FILE = '~/.git_cl_description_backup'
36 38
37 def DieWithError(message): 39 def DieWithError(message):
38 print >>sys.stderr, message 40 print >>sys.stderr, message
39 sys.exit(1) 41 sys.exit(1)
40 42
41 43
42 def Popen(cmd, **kwargs): 44 def Popen(cmd, **kwargs):
43 """Wrapper for subprocess.Popen() that logs and watch for cygwin issues""" 45 """Wrapper for subprocess.Popen() that logs and watch for cygwin issues"""
44 logging.info('Popen: ' + ' '.join(cmd)) 46 logging.info('Popen: ' + ' '.join(cmd))
(...skipping 489 matching lines...) Expand 10 before | Expand all | Expand 10 after
534 SetProperty('tree-status-url', 'STATUS', unset_error_ok=True) 536 SetProperty('tree-status-url', 'STATUS', unset_error_ok=True)
535 SetProperty('viewvc-url', 'VIEW_VC', unset_error_ok=True) 537 SetProperty('viewvc-url', 'VIEW_VC', unset_error_ok=True)
536 538
537 if 'PUSH_URL_CONFIG' in keyvals and 'ORIGIN_URL_CONFIG' in keyvals: 539 if 'PUSH_URL_CONFIG' in keyvals and 'ORIGIN_URL_CONFIG' in keyvals:
538 #should be of the form 540 #should be of the form
539 #PUSH_URL_CONFIG: url.ssh://gitrw.chromium.org.pushinsteadof 541 #PUSH_URL_CONFIG: url.ssh://gitrw.chromium.org.pushinsteadof
540 #ORIGIN_URL_CONFIG: http://src.chromium.org/git 542 #ORIGIN_URL_CONFIG: http://src.chromium.org/git
541 RunGit(['config', keyvals['PUSH_URL_CONFIG'], 543 RunGit(['config', keyvals['PUSH_URL_CONFIG'],
542 keyvals['ORIGIN_URL_CONFIG']]) 544 keyvals['ORIGIN_URL_CONFIG']])
543 545
544 # Update the hooks if the local hook files aren't present already.
545 if GetProperty('GITCL_PREUPLOAD') and not os.path.isfile(PREUPLOAD_HOOK):
546 DownloadToFile(GetProperty('GITCL_PREUPLOAD'), PREUPLOAD_HOOK)
547 if GetProperty('GITCL_PREDCOMMIT') and not os.path.isfile(PREDCOMMIT_HOOK):
548 DownloadToFile(GetProperty('GITCL_PREDCOMMIT'), PREDCOMMIT_HOOK)
549 return 0
550
551 546
552 @usage('[repo root containing codereview.settings]') 547 @usage('[repo root containing codereview.settings]')
553 def CMDconfig(parser, args): 548 def CMDconfig(parser, args):
554 """edit configuration for this tree""" 549 """edit configuration for this tree"""
555 550
556 (options, args) = parser.parse_args(args) 551 (options, args) = parser.parse_args(args)
557 if len(args) == 0: 552 if len(args) == 0:
558 GetCodereviewSettingsInteractively() 553 GetCodereviewSettingsInteractively()
559 return 0 554 return 0
560 555
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
662 return 657 return
663 658
664 fileobj = open(filename) 659 fileobj = open(filename)
665 text = fileobj.read() 660 text = fileobj.read()
666 fileobj.close() 661 fileobj.close()
667 os.remove(filename) 662 os.remove(filename)
668 stripcomment_re = re.compile(r'^#.*$', re.MULTILINE) 663 stripcomment_re = re.compile(r'^#.*$', re.MULTILINE)
669 return stripcomment_re.sub('', text).strip() 664 return stripcomment_re.sub('', text).strip()
670 665
671 666
672 def RunHook(hook, upstream_branch, error_ok=False): 667 def ConvertToInteger(inputval):
673 """Run a given hook if it exists. By default, we fail on errors.""" 668 """Convert a string to integer, but returns either an int or None."""
674 hook = '%s/%s' % (settings.GetRoot(), hook) 669 try:
675 if not os.path.exists(hook): 670 return int(inputval)
676 return 671 except (TypeError, ValueError):
677 return RunCommand([hook, upstream_branch], error_ok=error_ok, 672 return None
678 redirect_stdout=False) 673
674
675 def RunHook(committing, upstream_branch):
676 import presubmit_support
677 import scm
678 import watchlists
679
680 root = RunCommand(['git', 'rev-parse', '--show-cdup']).strip()
681 if not root:
682 root = "."
chase 2011/03/14 21:05:47 my original lines in git_cl_hooks.py should have u
683 absroot = os.path.abspath(root)
684 if not root:
685 raise Exception("Could not get root directory.")
chase 2011/03/14 21:05:47 my original lines in git_cl_hooks.py should have u
686
687 # We use the sha1 of HEAD as a name of this change.
688 name = RunCommand(['git', 'rev-parse', 'HEAD']).strip()
689 files = scm.GIT.CaptureStatus([root], upstream_branch)
690
691 cl = Changelist()
692 issue = ConvertToInteger(cl.GetIssue())
693 patchset = ConvertToInteger(cl.GetPatchset())
694 if issue:
695 description = cl.GetDescription()
696 else:
697 # If the change was never uploaded, use the log messages of all commits
698 # up to the branch point, as git cl upload will prefill the description
699 # with these log messages.
700 description = RunCommand(['git', 'log', '--pretty=format:%s%n%n%b',
701 '%s...' % (upstream_branch)]).strip()
chase 2011/03/14 21:05:47 indent one char
702 change = presubmit_support.GitChange(name, description, absroot, files,
703 issue, patchset)
704
705 # Apply watchlists on upload.
706 if not committing:
707 watchlist = watchlists.Watchlists(change.RepositoryRoot())
708 files = [f.LocalPath() for f in change.AffectedFiles()]
709 watchers = watchlist.GetWatchersForPaths(files)
710 RunCommand(['git', 'config', '--replace-all',
711 'rietveld.extracc', ','.join(watchers)])
chase 2011/03/14 21:05:47 indent one char
712
713 return presubmit_support.DoPresubmitChecks(change, committing,
714 verbose=None, output_stream=sys.stdout, input_stream=sys.stdin,
715 default_presubmit=None, may_prompt=None)
679 716
680 717
681 def CMDpresubmit(parser, args): 718 def CMDpresubmit(parser, args):
682 """run presubmit tests on the current changelist""" 719 """run presubmit tests on the current changelist"""
683 parser.add_option('--upload', action='store_true', 720 parser.add_option('--upload', action='store_true',
684 help='Run upload hook instead of the push/dcommit hook') 721 help='Run upload hook instead of the push/dcommit hook')
685 (options, args) = parser.parse_args(args) 722 (options, args) = parser.parse_args(args)
686 723
687 # Make sure index is up-to-date before running diff-index. 724 # Make sure index is up-to-date before running diff-index.
688 RunGit(['update-index', '--refresh', '-q'], error_ok=True) 725 RunGit(['update-index', '--refresh', '-q'], error_ok=True)
689 if RunGit(['diff-index', 'HEAD']): 726 if RunGit(['diff-index', 'HEAD']):
690 # TODO(maruel): Is this really necessary? 727 # TODO(maruel): Is this really necessary?
691 print 'Cannot presubmit with a dirty tree. You must commit locally first.' 728 print 'Cannot presubmit with a dirty tree. You must commit locally first.'
692 return 1 729 return 1
693 730
694 if args: 731 if args:
695 base_branch = args[0] 732 base_branch = args[0]
696 else: 733 else:
697 # Default to diffing against the "upstream" branch. 734 # Default to diffing against the "upstream" branch.
698 base_branch = Changelist().GetUpstreamBranch() 735 base_branch = Changelist().GetUpstreamBranch()
699 736
700 if options.upload: 737 if options.upload:
701 print '*** Presubmit checks for UPLOAD would report: ***' 738 print '*** Presubmit checks for UPLOAD would report: ***'
702 return not RunHook(PREUPLOAD_HOOK, upstream_branch=base_branch, 739 return RunHook(committing=False, upstream_branch=base_branch)
703 error_ok=True)
704 else: 740 else:
705 print '*** Presubmit checks for DCOMMIT would report: ***' 741 print '*** Presubmit checks for DCOMMIT would report: ***'
706 return not RunHook(PREDCOMMIT_HOOK, upstream_branch=base_branch, 742 return RunHook(committing=True, upstream_branch=base_branch)
707 error_ok=True)
708 743
709 744
710 @usage('[args to "git diff"]') 745 @usage('[args to "git diff"]')
711 def CMDupload(parser, args): 746 def CMDupload(parser, args):
712 """upload the current changelist to codereview""" 747 """upload the current changelist to codereview"""
713 parser.add_option('--bypass-hooks', action='store_true', dest='bypass_hooks', 748 parser.add_option('--bypass-hooks', action='store_true', dest='bypass_hooks',
714 help='bypass upload presubmit hook') 749 help='bypass upload presubmit hook')
715 parser.add_option('-m', dest='message', help='message for patch') 750 parser.add_option('-m', dest='message', help='message for patch')
716 parser.add_option('-r', '--reviewers', 751 parser.add_option('-r', '--reviewers',
717 help='reviewer email addresses') 752 help='reviewer email addresses')
(...skipping 18 matching lines...) Expand all
736 771
737 cl = Changelist() 772 cl = Changelist()
738 if args: 773 if args:
739 base_branch = args[0] 774 base_branch = args[0]
740 else: 775 else:
741 # Default to diffing against the "upstream" branch. 776 # Default to diffing against the "upstream" branch.
742 base_branch = cl.GetUpstreamBranch() 777 base_branch = cl.GetUpstreamBranch()
743 args = [base_branch + "..."] 778 args = [base_branch + "..."]
744 779
745 if not options.bypass_hooks: 780 if not options.bypass_hooks:
746 RunHook(PREUPLOAD_HOOK, upstream_branch=base_branch, error_ok=False) 781 RunHook(committing=False, upstream_branch=base_branch)
747 782
748 # --no-ext-diff is broken in some versions of Git, so try to work around 783 # --no-ext-diff is broken in some versions of Git, so try to work around
749 # this by overriding the environment (but there is still a problem if the 784 # this by overriding the environment (but there is still a problem if the
750 # git config key "diff.external" is used). 785 # git config key "diff.external" is used).
751 env = os.environ.copy() 786 env = os.environ.copy()
752 if 'GIT_EXTERNAL_DIFF' in env: 787 if 'GIT_EXTERNAL_DIFF' in env:
753 del env['GIT_EXTERNAL_DIFF'] 788 del env['GIT_EXTERNAL_DIFF']
754 subprocess.call(['git', 'diff', '--no-ext-diff', '--stat', '-M'] + args, 789 subprocess.call(['git', 'diff', '--no-ext-diff', '--stat', '-M'] + args,
755 env=env) 790 env=env)
756 791
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
893 '--pretty=format:%H']) 928 '--pretty=format:%H'])
894 extra_commits = RunGit(['rev-list', '^' + svn_head, base_branch]) 929 extra_commits = RunGit(['rev-list', '^' + svn_head, base_branch])
895 if extra_commits: 930 if extra_commits:
896 print ('This branch has %d additional commits not upstreamed yet.' 931 print ('This branch has %d additional commits not upstreamed yet.'
897 % len(extra_commits.splitlines())) 932 % len(extra_commits.splitlines()))
898 print ('Upstream "%s" or rebase this branch on top of the upstream trunk ' 933 print ('Upstream "%s" or rebase this branch on top of the upstream trunk '
899 'before attempting to %s.' % (base_branch, cmd)) 934 'before attempting to %s.' % (base_branch, cmd))
900 return 1 935 return 1
901 936
902 if not options.force and not options.bypass_hooks: 937 if not options.force and not options.bypass_hooks:
903 RunHook(PREDCOMMIT_HOOK, upstream_branch=base_branch, error_ok=False) 938 RunHook(committing=False, upstream_branch=base_branch)
chase 2011/03/14 21:05:47 <strike>committing=True to match PREDCOMMIT_HOOK</
904 939
905 if cmd == 'dcommit': 940 if cmd == 'dcommit':
906 # Check the tree status if the tree status URL is set. 941 # Check the tree status if the tree status URL is set.
907 status = GetTreeStatus() 942 status = GetTreeStatus()
908 if 'closed' == status: 943 if 'closed' == status:
909 print ('The tree is closed. Please wait for it to reopen. Use ' 944 print ('The tree is closed. Please wait for it to reopen. Use '
910 '"git cl dcommit -f" to commit on a closed tree.') 945 '"git cl dcommit -f" to commit on a closed tree.')
911 return 1 946 return 1
912 elif 'unknown' == status: 947 elif 'unknown' == status:
913 print ('Unable to determine tree status. Please verify manually and ' 948 print ('Unable to determine tree status. Please verify manually and '
(...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after
1279 ('AppEngine is misbehaving and returned HTTP %d, again. Keep faith ' 1314 ('AppEngine is misbehaving and returned HTTP %d, again. Keep faith '
1280 'and retry or visit go/isgaeup.\n%s') % (e.code, str(e))) 1315 'and retry or visit go/isgaeup.\n%s') % (e.code, str(e)))
1281 1316
1282 # Not a known command. Default to help. 1317 # Not a known command. Default to help.
1283 GenUsage(parser, 'help') 1318 GenUsage(parser, 'help')
1284 return CMDhelp(parser, argv) 1319 return CMDhelp(parser, argv)
1285 1320
1286 1321
1287 if __name__ == '__main__': 1322 if __name__ == '__main__':
1288 sys.exit(main(sys.argv[1:])) 1323 sys.exit(main(sys.argv[1:]))
OLDNEW
« no previous file with comments | « no previous file | git_cl/test/hooks.sh » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698