diff --git a/git_cl/git_cl.py b/git_cl/git_cl.py index be11cb3a7..5bbab8018 100644 --- a/git_cl/git_cl.py +++ b/git_cl/git_cl.py @@ -7,6 +7,7 @@ import logging import optparse import os import re +import StringIO import subprocess import sys import tempfile @@ -37,7 +38,7 @@ POSTUPSTREAM_HOOK_PATTERN = '.git/hooks/post-cl-%s' DESCRIPTION_BACKUP_FILE = '~/.git_cl_description_backup' def DieWithError(message): - print >>sys.stderr, message + print >> sys.stderr, message sys.exit(1) @@ -481,6 +482,76 @@ def GetCodereviewSettingsInteractively(): # svn-based hackery. +class HookResults(object): + """Contains the parsed output of the presubmit hooks.""" + def __init__(self, output_from_hooks=None): + self.reviewers = [] + self.output = None + self._ParseOutputFromHooks(output_from_hooks) + + def _ParseOutputFromHooks(self, output_from_hooks): + if not output_from_hooks: + return + lines = [] + reviewers = [] + reviewer_regexp = re.compile('ADD: R=(.+)') + for l in output_from_hooks.splitlines(): + m = reviewer_regexp.match(l) + if m: + reviewers.extend(m.group(1).split(',')) + else: + lines.append(l) + self.output = '\n'.join(lines) + self.reviewers = ','.join(reviewers) + + +class ChangeDescription(object): + """Contains a parsed form of the change description.""" + def __init__(self, subject, log_desc, reviewers): + self.subject = subject + self.log_desc = log_desc + self.reviewers = reviewers + self.description = self.log_desc + + def Update(self): + initial_text = """# Enter a description of the change. +# This will displayed on the codereview site. +# The first line will also be used as the subject of the review. +""" + initial_text += self.description + if 'R=' not in self.description and self.reviewers: + initial_text += '\nR=' + self.reviewers + if 'BUG=' not in self.description: + initial_text += '\nBUG=' + if 'TEST=' not in self.description: + initial_text += '\nTEST=' + self._ParseDescription(UserEditedLog(initial_text)) + + def _ParseDescription(self, description): + if not description: + self.description = description + return + + parsed_lines = [] + reviewers_regexp = re.compile('\s*R=(.+)') + reviewers = '' + subject = '' + for l in description.splitlines(): + if not subject: + subject = l + matched_reviewers = reviewers_regexp.match(l) + if matched_reviewers: + reviewers = matched_reviewers.group(1) + parsed_lines.append(l) + + self.description = '\n'.join(parsed_lines) + '\n' + self.subject = subject + self.reviewers = reviewers + + def IsEmpty(self): + return not self.description + + def FindCodereviewSettingsFile(filename='codereview.settings'): """Finds the given file starting in the cwd and going up. @@ -503,15 +574,6 @@ def FindCodereviewSettingsFile(filename='codereview.settings'): def LoadCodereviewSettingsFromFile(fileobj): """Parse a codereview.settings file and updates hooks.""" - def DownloadToFile(url, filename): - filename = os.path.join(settings.GetRoot(), filename) - contents = urllib2.urlopen(url).read() - fileobj = open(filename, 'w') - fileobj.write(contents) - fileobj.close() - os.chmod(filename, 0755) - return 0 - keyvals = {} for line in fileobj.read().splitlines(): if not line or line.startswith("#"): @@ -519,9 +581,6 @@ def LoadCodereviewSettingsFromFile(fileobj): k, v = line.split(": ", 1) keyvals[k] = v - def GetProperty(name): - return keyvals.get(name) - def SetProperty(name, setting, unset_error_ok=False): fullname = 'rietveld.' + name if setting in keyvals: @@ -672,7 +731,8 @@ def ConvertToInteger(inputval): return None -def RunHook(committing, upstream_branch): +def RunHook(committing, upstream_branch, rietveld_server, tbr, may_prompt): + """Calls sys.exit() if the hook fails; returns a HookResults otherwise.""" import presubmit_support import scm import watchlists @@ -710,9 +770,19 @@ def RunHook(committing, upstream_branch): RunCommand(['git', 'config', '--replace-all', 'rietveld.extracc', ','.join(watchers)]) - return presubmit_support.DoPresubmitChecks(change, committing, - verbose=None, output_stream=sys.stdout, input_stream=sys.stdin, - default_presubmit=None, may_prompt=None) + output = StringIO.StringIO() + res = presubmit_support.DoPresubmitChecks(change, committing, + verbose=None, output_stream=output, input_stream=sys.stdin, + default_presubmit=None, may_prompt=may_prompt, tbr=tbr, + host_url=cl.GetRietveldServer()) + hook_results = HookResults(output.getvalue()) + if hook_results.output: + print hook_results.output + + # TODO(dpranke): We should propagate the error out instead of calling exit(). + if not res: + sys.exit(1) + return hook_results def CMDpresubmit(parser, args): @@ -728,18 +798,25 @@ def CMDpresubmit(parser, args): print 'Cannot presubmit with a dirty tree. You must commit locally first.' return 1 + cl = Changelist() if args: base_branch = args[0] else: # Default to diffing against the "upstream" branch. - base_branch = Changelist().GetUpstreamBranch() + base_branch = cl.GetUpstreamBranch() if options.upload: print '*** Presubmit checks for UPLOAD would report: ***' - return RunHook(committing=False, upstream_branch=base_branch) + RunHook(committing=False, upstream_branch=base_branch, + rietveld_server=cl.GetRietveldServer(), tbr=False, + may_prompt=False) + return 0 else: print '*** Presubmit checks for DCOMMIT would report: ***' - return RunHook(committing=True, upstream_branch=base_branch) + RunHook(committing=True, upstream_branch=base_branch, + rietveld_server=cl.GetRietveldServer, tbr=False, + may_prompt=False) + return 0 @usage('[args to "git diff"]') @@ -747,6 +824,8 @@ def CMDupload(parser, args): """upload the current changelist to codereview""" parser.add_option('--bypass-hooks', action='store_true', dest='bypass_hooks', help='bypass upload presubmit hook') + parser.add_option('-f', action='store_true', dest='force', + help="force yes to questions (don't prompt)") parser.add_option('-m', dest='message', help='message for patch') parser.add_option('-r', '--reviewers', help='reviewer email addresses') @@ -778,7 +857,14 @@ def CMDupload(parser, args): args = [base_branch + "..."] if not options.bypass_hooks: - RunHook(committing=False, upstream_branch=base_branch) + hook_results = RunHook(committing=False, upstream_branch=base_branch, + rietveld_server=cl.GetRietveldServer(), tbr=False, + may_prompt=(not options.force)) + else: + hook_results = HookResults() + + if not options.reviewers and hook_results.reviewers: + options.reviewers = hook_results.reviewers # --no-ext-diff is broken in some versions of Git, so try to work around # this by overriding the environment (but there is still a problem if the @@ -791,8 +877,6 @@ def CMDupload(parser, args): upload_args = ['--assume_yes'] # Don't ask about untracked files. upload_args.extend(['--server', cl.GetRietveldServer()]) - if options.reviewers: - upload_args.extend(['--reviewers', options.reviewers]) if options.emulate_svn_auto_props: upload_args.append('--emulate_svn_auto_props') if options.send_mail: @@ -813,28 +897,19 @@ def CMDupload(parser, args): "Adding patch to that issue." % cl.GetIssue()) else: log_desc = CreateDescriptionFromLog(args) - if options.from_logs: - # Uses logs as description and message as subject. - subject = options.message - change_desc = subject + '\n\n' + log_desc - else: - initial_text = """# Enter a description of the change. -# This will displayed on the codereview site. -# The first line will also be used as the subject of the review. -""" - if 'BUG=' not in log_desc: - log_desc += '\nBUG=' - if 'TEST=' not in log_desc: - log_desc += '\nTEST=' - change_desc = UserEditedLog(initial_text + log_desc) - subject = '' - if change_desc: - subject = change_desc.splitlines()[0] - if not change_desc: + change_desc = ChangeDescription(options.message, log_desc, + options.reviewers) + if not options.from_logs: + change_desc.Update() + + if change_desc.IsEmpty(): print "Description is empty; aborting." return 1 - upload_args.extend(['--message', subject]) - upload_args.extend(['--description', change_desc]) + + upload_args.extend(['--message', change_desc.subject]) + upload_args.extend(['--description', change_desc.description]) + if change_desc.reviewers: + upload_args.extend(['--reviewers', change_desc.reviewers]) cc = ','.join(filter(None, (settings.GetCCList(), options.cc))) if cc: upload_args.extend(['--cc', cc]) @@ -866,7 +941,7 @@ def CMDupload(parser, args): print '\nGot exception while uploading -- saving description to %s\n' \ % backup_path backup_file = open(backup_path, 'w') - backup_file.write(change_desc) + backup_file.write(change_desc.description) backup_file.close() raise @@ -934,9 +1009,12 @@ def SendUpstream(parser, args, cmd): 'before attempting to %s.' % (base_branch, cmd)) return 1 - if not options.force and not options.bypass_hooks: - RunHook(committing=False, upstream_branch=base_branch) + if not options.bypass_hooks: + RunHook(committing=True, upstream_branch=base_branch, + rietveld_server=cl.GetRietveldServer(), tbr=options.tbr, + may_prompt=(not options.force)) + if not options.force and not options.bypass_hooks: if cmd == 'dcommit': # Check the tree status if the tree status URL is set. status = GetTreeStatus() @@ -975,6 +1053,7 @@ def SendUpstream(parser, args, cmd): if cl.GetIssue(): description = cl.GetDescription() + # TODO(dpranke): Update to use ChangeDescription object. if not description: description = """# Enter a description of the change. # This will be used as the change log for the commit. @@ -1066,7 +1145,7 @@ def SendUpstream(parser, args, cmd): if retcode == 0: hook = POSTUPSTREAM_HOOK_PATTERN % cmd if os.path.isfile(hook): - RunHook(hook, upstream_branch=base_branch, error_ok=True) + RunCommand([hook, base_branch], error_ok=True) return 0 @@ -1202,9 +1281,9 @@ def GetTreeStatus(): elif status.find('open') != -1 or status == '1': return 'open' return 'unknown' - return 'unset' + def GetTreeStatusReason(): """Fetches the tree status from a json url and returns the message with the reason for the tree to be opened or closed.""" @@ -1230,6 +1309,7 @@ def GetTreeStatusReason(): connection.close() return status['message'] + def CMDtree(parser, args): """show the status of the tree""" (options, args) = parser.parse_args(args) diff --git a/git_cl/test/owners.sh b/git_cl/test/owners.sh new file mode 100755 index 000000000..4c3ad7200 --- /dev/null +++ b/git_cl/test/owners.sh @@ -0,0 +1,46 @@ +#!/bin/bash + +set -e + +. ./test-lib.sh + +setup_initsvn +setup_gitsvn + +( + + set -e + cd git-svn + git config rietveld.server localhost:8080 + export EDITOR=$(which true) + + git checkout -q -b work + echo "ben@chromium.org" > OWNERS + cat < PRESUBMIT.py +def CheckChangeOnCommit(input_api, output_api): + return input_api.canned_checks.CheckOwners(input_api, output_api) + +CheckChangeOnUpload = CheckChangeOnCommit +END + + git add OWNERS PRESUBMIT.py ; git commit -q -m "add OWNERS" + + test_expect_success "upload succeeds (needs a server running on localhost)" \ + "$GIT_CL upload -m test master | grep -q 'Issue created'" + + test_expect_success "git-cl status has a suggested reviewer" \ + "$GIT_CL status | grep -q 'R=ben@chromium.org'" + + test_expect_failure "git-cl dcommit fails w/ missing LGTM" \ + "$GIT_CL dcommit" + + test_expect_success "git-cl dcommit --tbr succeeds" \ + "$GIT_CL dcommit --tbr -f | grep -q -- '--tbr was specified'" +) +SUCCESS=$? + +cleanup + +if [ $SUCCESS == 0 ]; then + echo PASS +fi diff --git a/git_cl/test/post-dcommit-hook-test.sh b/git_cl/test/post-dcommit-hook-test.sh deleted file mode 100755 index cd3ecbe7f..000000000 --- a/git_cl/test/post-dcommit-hook-test.sh +++ /dev/null @@ -1,37 +0,0 @@ -#!/bin/bash - -set -e - -. ./test-lib.sh - -setup_initsvn -setup_gitsvn - -( - set -e - cd git-svn - - cat > .git/hooks/post-cl-dcommit << _EOF -#!/bin/bash -git branch -m COMMITTED -_EOF - chmod +x .git/hooks/post-cl-dcommit - - git config rietveld.server localhost:1 - git checkout -q --track -b work - echo "some work done" >> test - git add test; git commit -q -m "work" - - test_expect_success "dcommitted code" \ - "$GIT_CL dcommit -f --tbr --bypass-hooks -m 'dcommit'" - - test_expect_success "post-cl-dcommit hook executed" \ - "git symbolic-ref HEAD | grep -q COMMITTED" -) -SUCCESS=$? - -cleanup - -if [ $SUCCESS == 0 ]; then - echo PASS -fi diff --git a/presubmit_canned_checks.py b/presubmit_canned_checks.py index b3d36199f..40df31a59 100644 --- a/presubmit_canned_checks.py +++ b/presubmit_canned_checks.py @@ -626,10 +626,13 @@ def CheckBuildbotPendingBuilds(input_api, output_api, url, max_pendings, return [] -def CheckOwners(input_api, output_api, source_file_filter=None): +def CheckOwners(input_api, output_api, email_regexp=None, + source_file_filter=None): affected_files = set([f.LocalPath() for f in input_api.change.AffectedFiles(source_file_filter)]) owners_db = input_api.owners_db + if email_regexp: + owners_db.email_regexp = input_api.re.compile(email_regexp) if input_api.is_committing and input_api.tbr: return [output_api.PresubmitNotifyResult( diff --git a/presubmit_support.py b/presubmit_support.py index 4c12912dc..fc1c7f23b 100755 --- a/presubmit_support.py +++ b/presubmit_support.py @@ -154,19 +154,12 @@ class OutputApi(object): """Whether this presubmit result should result in a prompt warning.""" return False - def IsMessage(self): - """Whether this result contains anything needing to be displayed.""" - return True - class PresubmitAddText(PresubmitResult): """Propagates a line of text back to the caller.""" def __init__(self, message, items=None, long_text=''): super(OutputApi.PresubmitAddText, self).__init__("ADD: " + message, items, long_text) - def IsMessage(self): - return False - class PresubmitError(PresubmitResult): """A hard presubmit error.""" def IsFatal(self): @@ -229,14 +222,15 @@ class InputApi(object): # TODO(dpranke): Update callers to pass in tbr, host_url, remove # default arguments. - def __init__(self, change, presubmit_path, is_committing, tbr=False, - host_url='http://codereview.chromium.org'): + def __init__(self, change, presubmit_path, is_committing, tbr, host_url=None): """Builds an InputApi object. Args: change: A presubmit.Change object. presubmit_path: The path to the presubmit script being processed. is_committing: True if the change is about to be committed. + tbr: True if '--tbr' was passed to skip any reviewer/owner checks + host_url: scheme, host, and path of rietveld instance """ # Version number of the presubmit_support script. self.version = [int(x) for x in __version__.split('.')] @@ -244,6 +238,7 @@ class InputApi(object): self.host_url = host_url self.is_committing = is_committing self.tbr = tbr + self.host_url = host_url or 'http://codereview.chromium.org' # We expose various modules and functions as attributes of the input_api # so that presubmit scripts don't have to import them. @@ -935,14 +930,19 @@ def DoGetTrySlaves(changed_files, class PresubmitExecuter(object): - def __init__(self, change, committing): + def __init__(self, change, committing, tbr, host_url): """ Args: change: The Change object. committing: True if 'gcl commit' is running, False if 'gcl upload' is. + tbr: True if '--tbr' was passed to skip any reviewer/owner checks + host_url: scheme, host, and path of rietveld instance + (or None for default) """ self.change = change self.committing = committing + self.tbr = tbr + self.host_url = host_url def ExecPresubmitScript(self, script_text, presubmit_path): """Executes a single presubmit script. @@ -961,7 +961,8 @@ class PresubmitExecuter(object): os.chdir(os.path.dirname(presubmit_path)) # Load the presubmit script into context. - input_api = InputApi(self.change, presubmit_path, self.committing) + input_api = InputApi(self.change, presubmit_path, self.committing, + self.tbr, self.host_url) context = {} exec script_text in context @@ -992,14 +993,16 @@ class PresubmitExecuter(object): os.chdir(main_path) return result - +# TODO(dpranke): make all callers pass in tbr, host_url? def DoPresubmitChecks(change, committing, verbose, output_stream, input_stream, default_presubmit, - may_prompt): + may_prompt, + tbr=False, + host_url=None): """Runs all presubmit checks that apply to the files in the change. This finds all PRESUBMIT.py files in directories enclosing the files in the @@ -1017,6 +1020,9 @@ def DoPresubmitChecks(change, input_stream: A stream to read input from the user. default_presubmit: A default presubmit script to execute in any case. may_prompt: Enable (y/n) questions on warning or error. + tbr: was --tbr specified to skip any reviewer/owner checks? + host_url: scheme, host, and port of host to use for rietveld-related + checks Warning: If may_prompt is true, output_stream SHOULD be sys.stdout and input_stream @@ -1032,7 +1038,7 @@ def DoPresubmitChecks(change, if not presubmit_files and verbose: output_stream.write("Warning, no presubmit.py found.\n") results = [] - executer = PresubmitExecuter(change, committing) + executer = PresubmitExecuter(change, committing, tbr, host_url) if default_presubmit: if verbose: output_stream.write("Running default presubmit script.\n") @@ -1064,9 +1070,6 @@ def DoPresubmitChecks(change, if items: output_stream.write('** Presubmit %s **\n' % name) for item in items: - if not item.IsMessage(): - continue - # Access to a protected member XXX of a client class # pylint: disable=W0212 if not item._Handle(output_stream, input_stream, diff --git a/tests/presubmit_unittest.py b/tests/presubmit_unittest.py index bbe54b1c1..8f39b39b9 100755 --- a/tests/presubmit_unittest.py +++ b/tests/presubmit_unittest.py @@ -342,7 +342,7 @@ class PresubmitUnittest(PresubmitTestsBase): change = presubmit.Change('mychange', '\n'.join(description_lines), self.fake_root_dir, files, 0, 0) - executer = presubmit.PresubmitExecuter(change, False) + executer = presubmit.PresubmitExecuter(change, False, False, None) self.failIf(executer.ExecPresubmitScript('', fake_presubmit)) # No error if no on-upload entry point self.failIf(executer.ExecPresubmitScript( @@ -351,7 +351,7 @@ class PresubmitUnittest(PresubmitTestsBase): fake_presubmit )) - executer = presubmit.PresubmitExecuter(change, True) + executer = presubmit.PresubmitExecuter(change, True, False, None) # No error if no on-commit entry point self.failIf(executer.ExecPresubmitScript( ('def CheckChangeOnUpload(input_api, output_api):\n' @@ -706,7 +706,8 @@ class InputApiUnittest(PresubmitTestsBase): 'version', ] # If this test fails, you should add the relevant test. - self.compareMembers(presubmit.InputApi(self.fake_change, './.', False), + self.compareMembers(presubmit.InputApi(self.fake_change, './.', False, + False, None), members) def testDepotToLocalPath(self): @@ -715,31 +716,32 @@ class InputApiUnittest(PresubmitTestsBase): presubmit.scm.SVN.CaptureInfo('svn:/foo/notfound/burp').AndReturn({}) self.mox.ReplayAll() - path = presubmit.InputApi(self.fake_change, './p', False).DepotToLocalPath( - 'svn://foo/smurf') + path = presubmit.InputApi(self.fake_change, './p', False, False, + None).DepotToLocalPath('svn://foo/smurf') self.failUnless(path == 'prout') - path = presubmit.InputApi(self.fake_change, './p', False).DepotToLocalPath( - 'svn:/foo/notfound/burp') + path = presubmit.InputApi(self.fake_change, './p', False, False, + None).DepotToLocalPath('svn:/foo/notfound/burp') self.failUnless(path == None) def testLocalToDepotPath(self): presubmit.scm.SVN.CaptureInfo('smurf').AndReturn({'URL': 'svn://foo'}) presubmit.scm.SVN.CaptureInfo('notfound-food').AndReturn({}) self.mox.ReplayAll() - path = presubmit.InputApi(self.fake_change, './p', False).LocalToDepotPath( - 'smurf') + path = presubmit.InputApi(self.fake_change, './p', False, False, + None).LocalToDepotPath('smurf') self.assertEqual(path, 'svn://foo') - path = presubmit.InputApi(self.fake_change, './p', False).LocalToDepotPath( - 'notfound-food') + path = presubmit.InputApi(self.fake_change, './p', False, False, + None).LocalToDepotPath('notfound-food') self.failUnless(path == None) def testInputApiConstruction(self): self.mox.ReplayAll() api = presubmit.InputApi(self.fake_change, presubmit_path='foo/path/PRESUBMIT.py', - is_committing=False) + is_committing=False, tbr=False, host_url=None) self.assertEquals(api.PresubmitLocalPath(), 'foo/path') self.assertEquals(api.change, self.fake_change) + self.assertEquals(api.host_url, 'http://codereview.chromium.org') def testInputApiPresubmitScriptFiltering(self): join = presubmit.os.path.join @@ -795,7 +797,7 @@ class InputApiUnittest(PresubmitTestsBase): input_api = presubmit.InputApi(change, join(self.fake_root_dir, 'foo', 'PRESUBMIT.py'), - False) + False, False, None) # Doesn't filter much got_files = input_api.AffectedFiles() self.assertEquals(len(got_files), 7) @@ -880,7 +882,8 @@ class InputApiUnittest(PresubmitTestsBase): ], ), ] - input_api = presubmit.InputApi(self.fake_change, './PRESUBMIT.py', False) + input_api = presubmit.InputApi(self.fake_change, './PRESUBMIT.py', False, + False, None) self.mox.ReplayAll() self.assertEqual(len(input_api.DEFAULT_WHITE_LIST), 22) @@ -911,7 +914,7 @@ class InputApiUnittest(PresubmitTestsBase): input_api = presubmit.InputApi(change, presubmit.os.path.join(self.fake_root_dir, 'PRESUBMIT.py'), - False) + False, False, None) got_files = input_api.AffectedSourceFiles(FilterSourceFile) self.assertEquals(len(got_files), 2) self.assertEquals(got_files[0].LocalPath(), 'eeaee') @@ -930,7 +933,8 @@ class InputApiUnittest(PresubmitTestsBase): change = presubmit.SvnChange('mychange', '', self.fake_root_dir, files, 0, 0) - input_api = presubmit.InputApi(change, './PRESUBMIT.py', False) + input_api = presubmit.InputApi(change, './PRESUBMIT.py', False, + False, None) # Sample usage of overiding the default white and black lists. got_files = input_api.AffectedSourceFiles( lambda x: input_api.FilterSourceFile(x, white_list, black_list)) @@ -970,7 +974,7 @@ class InputApiUnittest(PresubmitTestsBase): presubmit_path = join(self.fake_root_dir, 'isdir', 'PRESUBMIT.py') api = presubmit.InputApi(change=change, presubmit_path=presubmit_path, - is_committing=True) + is_committing=True, tbr=False, host_url=None) paths_from_api = api.AbsoluteLocalPaths(include_dirs=True) self.assertEqual(len(paths_from_api), 2) for absolute_paths in [paths_from_change, paths_from_api]: @@ -986,7 +990,8 @@ class InputApiUnittest(PresubmitTestsBase): change = presubmit.Change('mychange', '', self.fake_root_dir, [], 0, 0) api = presubmit.InputApi( change, - presubmit.os.path.join(self.fake_root_dir, 'foo', 'PRESUBMIT.py'), True) + presubmit.os.path.join(self.fake_root_dir, 'foo', 'PRESUBMIT.py'), True, + False, None) api.AffectedTextFiles(include_deletes=False) def testReadFileStringDenied(self): @@ -995,7 +1000,8 @@ class InputApiUnittest(PresubmitTestsBase): change = presubmit.Change('foo', 'foo', self.fake_root_dir, [('M', 'AA')], 0, 0) input_api = presubmit.InputApi( - change, presubmit.os.path.join(self.fake_root_dir, '/p'), False) + change, presubmit.os.path.join(self.fake_root_dir, '/p'), False, + False, None) self.assertRaises(IOError, input_api.ReadFile, 'boo', 'x') def testReadFileStringAccepted(self): @@ -1006,7 +1012,8 @@ class InputApiUnittest(PresubmitTestsBase): change = presubmit.Change('foo', 'foo', self.fake_root_dir, [('M', 'AA')], 0, 0) input_api = presubmit.InputApi( - change, presubmit.os.path.join(self.fake_root_dir, '/p'), False) + change, presubmit.os.path.join(self.fake_root_dir, '/p'), False, + False, None) input_api.ReadFile(path, 'x') def testReadFileAffectedFileDenied(self): @@ -1016,7 +1023,8 @@ class InputApiUnittest(PresubmitTestsBase): change = presubmit.Change('foo', 'foo', self.fake_root_dir, [('M', 'AA')], 0, 0) input_api = presubmit.InputApi( - change, presubmit.os.path.join(self.fake_root_dir, '/p'), False) + change, presubmit.os.path.join(self.fake_root_dir, '/p'), False, + False, None) self.assertRaises(IOError, input_api.ReadFile, fileobj, 'x') def testReadFileAffectedFileAccepted(self): @@ -1028,7 +1036,8 @@ class InputApiUnittest(PresubmitTestsBase): change = presubmit.Change('foo', 'foo', self.fake_root_dir, [('M', 'AA')], 0, 0) input_api = presubmit.InputApi( - change, presubmit.os.path.join(self.fake_root_dir, '/p'), False) + change, presubmit.os.path.join(self.fake_root_dir, '/p'), False, + False, None) input_api.ReadFile(fileobj, 'x') @@ -1046,23 +1055,17 @@ class OuputApiUnittest(PresubmitTestsBase): def testOutputApiBasics(self): self.mox.ReplayAll() self.failUnless(presubmit.OutputApi.PresubmitError('').IsFatal()) - self.failUnless(presubmit.OutputApi.PresubmitError('').IsMessage()) self.failIf(presubmit.OutputApi.PresubmitError('').ShouldPrompt()) self.failIf(presubmit.OutputApi.PresubmitPromptWarning('').IsFatal()) self.failUnless( presubmit.OutputApi.PresubmitPromptWarning('').ShouldPrompt()) - self.failUnless( - presubmit.OutputApi.PresubmitPromptWarning('').IsMessage()) self.failIf(presubmit.OutputApi.PresubmitNotifyResult('').IsFatal()) self.failIf(presubmit.OutputApi.PresubmitNotifyResult('').ShouldPrompt()) - self.failUnless( - presubmit.OutputApi.PresubmitNotifyResult('foo').IsMessage()) self.failIf(presubmit.OutputApi.PresubmitAddText('foo').IsFatal()) self.failIf(presubmit.OutputApi.PresubmitAddText('foo').ShouldPrompt()) - self.failIf(presubmit.OutputApi.PresubmitAddText('foo').IsMessage()) # TODO(joi) Test MailTextResult once implemented. @@ -1880,7 +1883,7 @@ mac|success|blew messages = list('{"sender": "' + a + '","text": "lgtm"}' for a in approvers) rietveld_response = ('{"owner": "john@example.com",' - '"messages": [' + ','.join(messages) + ']}') + '"messages": [' + ','.join(messages) + ']}') input_api.urllib2.urlopen( input_api.host_url + '/api/1?messages=true').AndReturn( StringIO.StringIO(rietveld_response))