Commit 2b9aa8e0 authored by maruel@chromium.org's avatar maruel@chromium.org

Refactor SubprocessCallAndFilter() to remove positional arguments.

This way the function is much more similar to subprocess.call(). Further changes
will be done, to be able to convert all the function, to be able to parallelize
output without corrupting it.

Used pylint to verify call graph correctness, causing some other unrelated
changes.

TEST=unit tests
BUG=none

Review URL: http://codereview.chromium.org/3117039

git-svn-id: svn://svn.chromium.org/chrome/trunk/tools/depot_tools@57369 0039d316-1c4b-4281-b951-d872f2087c98
parent 10ccd112
...@@ -143,12 +143,12 @@ def GetCachedFile(filename, max_age=60*60*24*3, use_root=False): ...@@ -143,12 +143,12 @@ def GetCachedFile(filename, max_age=60*60*24*3, use_root=False):
# stderr into content_array. # stderr into content_array.
content_array = [] content_array = []
svn_path = url_path + "/" + filename svn_path = url_path + "/" + filename
SVN.RunAndFilterOutput(['cat', svn_path, '--non-interactive'], '.', SVN.RunAndFilterOutput(['cat', svn_path, '--non-interactive'],
False, False, content_array.append) cwd='.', filter_fn=content_array.append)
# Exit the loop if the file was found. Override content. # Exit the loop if the file was found. Override content.
content = '\n'.join(content_array) content = '\n'.join(content_array)
break break
except gclient_utils.Error, e: except gclient_utils.Error:
if content_array[0].startswith( if content_array[0].startswith(
'svn: Can\'t get username or password'): 'svn: Can\'t get username or password'):
ErrorExit('Your svn credentials expired. Please run svn update ' ErrorExit('Your svn credentials expired. Please run svn update '
...@@ -716,7 +716,7 @@ def CMDstatus(): ...@@ -716,7 +716,7 @@ def CMDstatus():
@need_change_and_args @need_change_and_args
@attrs(usage='[--no_presubmit] [--clobber] [--no_watchlists]') @attrs(usage='[--no_presubmit] [--no_watchlists]')
def CMDupload(change_info, args): def CMDupload(change_info, args):
"""Uploads the changelist to the server for review. """Uploads the changelist to the server for review.
...@@ -736,9 +736,6 @@ def CMDupload(change_info, args): ...@@ -736,9 +736,6 @@ def CMDupload(change_info, args):
if FilterFlag(args, "--send-mail"): if FilterFlag(args, "--send-mail"):
args.append("--send_mail") args.append("--send_mail")
# Supports --clobber for the try server.
clobber = FilterFlag(args, "--clobber")
upload_arg = ["upload.py", "-y"] upload_arg = ["upload.py", "-y"]
server = GetCodeReviewSetting("CODE_REVIEW_SERVER") server = GetCodeReviewSetting("CODE_REVIEW_SERVER")
if not server: if not server:
......
...@@ -451,7 +451,8 @@ class Dependency(GClientKeywords, gclient_utils.WorkItem): ...@@ -451,7 +451,8 @@ class Dependency(GClientKeywords, gclient_utils.WorkItem):
# Use a discrete exit status code of 2 to indicate that a hook action # Use a discrete exit status code of 2 to indicate that a hook action
# failed. Users of this script may wish to treat hook action failures # failed. Users of this script may wish to treat hook action failures
# differently from VC failures. # differently from VC failures.
return gclient_utils.SubprocessCall(command, self.root_dir(), fail_status=2) return gclient_utils.SubprocessCall(command, cwd=self.root_dir(),
fail_status=2)
def root_dir(self): def root_dir(self):
return self.parent.root_dir() return self.parent.root_dir()
...@@ -605,7 +606,6 @@ solutions = [ ...@@ -605,7 +606,6 @@ solutions = [
'incomplete: %s' % s) 'incomplete: %s' % s)
# .gclient can have hooks. # .gclient can have hooks.
self.deps_hooks = config_dict.get('hooks', []) self.deps_hooks = config_dict.get('hooks', [])
self.direct_reference = True
self.deps_parsed = True self.deps_parsed = True
def SaveConfig(self): def SaveConfig(self):
...@@ -881,10 +881,10 @@ def CMDrecurse(parser, args): ...@@ -881,10 +881,10 @@ def CMDrecurse(parser, args):
scm = gclient_scm.GetScmName(url) scm = gclient_scm.GetScmName(url)
if scm_set and scm not in scm_set: if scm_set and scm not in scm_set:
continue continue
dir = os.path.normpath(os.path.join(root, path)) cwd = os.path.normpath(os.path.join(root, path))
env['GCLIENT_SCM'] = scm env['GCLIENT_SCM'] = scm
env['GCLIENT_URL'] = url env['GCLIENT_URL'] = url
subprocess.Popen(args, cwd=dir, env=env).communicate() subprocess.Popen(args, cwd=cwd, env=env).communicate()
@attr('usage', '[url] [safesync url]') @attr('usage', '[url] [safesync url]')
......
...@@ -154,7 +154,7 @@ class GitWrapper(SCMWrapper): ...@@ -154,7 +154,7 @@ class GitWrapper(SCMWrapper):
merge_base = self._Run(['merge-base', 'HEAD', 'origin']) merge_base = self._Run(['merge-base', 'HEAD', 'origin'])
command = ['diff', merge_base] command = ['diff', merge_base]
filterer = DiffFilterer(self.relpath) filterer = DiffFilterer(self.relpath)
scm.GIT.RunAndFilterOutput(command, path, False, False, filterer.Filter, scm.GIT.RunAndFilterOutput(command, cwd=path, filter_fn=filterer.Filter,
stdout=options.stdout) stdout=options.stdout)
def update(self, options, args, file_list): def update(self, options, args, file_list):
...@@ -644,7 +644,7 @@ class GitWrapper(SCMWrapper): ...@@ -644,7 +644,7 @@ class GitWrapper(SCMWrapper):
def _Run(self, args, cwd=None, redirect_stdout=True): def _Run(self, args, cwd=None, redirect_stdout=True):
# TODO(maruel): Merge with Capture or better gclient_utils.CheckCall(). # TODO(maruel): Merge with Capture or better gclient_utils.CheckCall().
if cwd is None: if cwd is None:
cwd = self.checkout_path cwd = self.checkout_path
stdout = None stdout = None
if redirect_stdout: if redirect_stdout:
stdout = subprocess.PIPE stdout = subprocess.PIPE
...@@ -671,18 +671,15 @@ class SVNWrapper(SCMWrapper): ...@@ -671,18 +671,15 @@ class SVNWrapper(SCMWrapper):
def cleanup(self, options, args, file_list): def cleanup(self, options, args, file_list):
"""Cleanup working copy.""" """Cleanup working copy."""
command = ['cleanup'] scm.SVN.Run(['cleanup'] + args,
command.extend(args) cwd=os.path.join(self._root_dir, self.relpath))
scm.SVN.Run(command, os.path.join(self._root_dir, self.relpath))
def diff(self, options, args, file_list): def diff(self, options, args, file_list):
# NOTE: This function does not currently modify file_list. # NOTE: This function does not currently modify file_list.
path = os.path.join(self._root_dir, self.relpath) path = os.path.join(self._root_dir, self.relpath)
if not os.path.isdir(path): if not os.path.isdir(path):
raise gclient_utils.Error('Directory %s is not present.' % path) raise gclient_utils.Error('Directory %s is not present.' % path)
command = ['diff'] scm.SVN.Run(['diff'] + args, cwd=path)
command.extend(args)
scm.SVN.Run(command, path)
def export(self, options, args, file_list): def export(self, options, args, file_list):
"""Export a clean directory tree into the given path.""" """Export a clean directory tree into the given path."""
...@@ -693,9 +690,8 @@ class SVNWrapper(SCMWrapper): ...@@ -693,9 +690,8 @@ class SVNWrapper(SCMWrapper):
except OSError: except OSError:
pass pass
assert os.path.exists(export_path) assert os.path.exists(export_path)
command = ['export', '--force', '.'] scm.SVN.Run(['export', '--force', '.', export_path],
command.append(export_path) cwd=os.path.join(self._root_dir, self.relpath))
scm.SVN.Run(command, os.path.join(self._root_dir, self.relpath))
def pack(self, options, args, file_list): def pack(self, options, args, file_list):
"""Generates a patch file which can be applied to the root of the """Generates a patch file which can be applied to the root of the
...@@ -707,7 +703,8 @@ class SVNWrapper(SCMWrapper): ...@@ -707,7 +703,8 @@ class SVNWrapper(SCMWrapper):
command.extend(args) command.extend(args)
filterer = DiffFilterer(self.relpath) filterer = DiffFilterer(self.relpath)
scm.SVN.RunAndFilterOutput(command, path, False, False, filterer.Filter, scm.SVN.RunAndFilterOutput(command, cwd=path, print_messages=False,
print_stdout=False, filter_fn=filterer.Filter,
stdout=options.stdout) stdout=options.stdout)
def update(self, options, args, file_list): def update(self, options, args, file_list):
...@@ -765,7 +762,7 @@ class SVNWrapper(SCMWrapper): ...@@ -765,7 +762,7 @@ class SVNWrapper(SCMWrapper):
dir_info = scm.SVN.CaptureStatus(os.path.join(checkout_path, '.')) dir_info = scm.SVN.CaptureStatus(os.path.join(checkout_path, '.'))
if [True for d in dir_info if d[0][2] == 'L' and d[1] == checkout_path]: if [True for d in dir_info if d[0][2] == 'L' and d[1] == checkout_path]:
# The current directory is locked, clean it up. # The current directory is locked, clean it up.
scm.SVN.Run(['cleanup'], checkout_path) scm.SVN.Run(['cleanup'], cwd=checkout_path)
# Retrieve the current HEAD version because svn is slow at null updates. # Retrieve the current HEAD version because svn is slow at null updates.
if options.manually_grab_svn_rev and not revision: if options.manually_grab_svn_rev and not revision:
...@@ -797,7 +794,7 @@ class SVNWrapper(SCMWrapper): ...@@ -797,7 +794,7 @@ class SVNWrapper(SCMWrapper):
from_info['Repository Root'], from_info['Repository Root'],
to_info['Repository Root'], to_info['Repository Root'],
self.relpath] self.relpath]
scm.SVN.Run(command, self._root_dir) scm.SVN.Run(command, cwd=self._root_dir)
from_info['URL'] = from_info['URL'].replace( from_info['URL'] = from_info['URL'].replace(
from_info['Repository Root'], from_info['Repository Root'],
to_info['Repository Root']) to_info['Repository Root'])
...@@ -840,7 +837,7 @@ class SVNWrapper(SCMWrapper): ...@@ -840,7 +837,7 @@ class SVNWrapper(SCMWrapper):
# Create an empty checkout and then update the one file we want. Future # Create an empty checkout and then update the one file we want. Future
# operations will only apply to the one file we checked out. # operations will only apply to the one file we checked out.
command = ["checkout", "--depth", "empty", self.url, checkout_path] command = ["checkout", "--depth", "empty", self.url, checkout_path]
scm.SVN.Run(command, self._root_dir) scm.SVN.Run(command, cwd=self._root_dir)
if os.path.exists(os.path.join(checkout_path, filename)): if os.path.exists(os.path.join(checkout_path, filename)):
os.remove(os.path.join(checkout_path, filename)) os.remove(os.path.join(checkout_path, filename))
command = ["update", filename] command = ["update", filename]
...@@ -860,7 +857,7 @@ class SVNWrapper(SCMWrapper): ...@@ -860,7 +857,7 @@ class SVNWrapper(SCMWrapper):
os.path.join(checkout_path, filename)] os.path.join(checkout_path, filename)]
command = self._AddAdditionalUpdateFlags(command, options, command = self._AddAdditionalUpdateFlags(command, options,
options.revision) options.revision)
scm.SVN.Run(command, self._root_dir) scm.SVN.Run(command, cwd=self._root_dir)
def revert(self, options, args, file_list): def revert(self, options, args, file_list):
"""Reverts local modifications. Subversion specific. """Reverts local modifications. Subversion specific.
......
...@@ -251,52 +251,51 @@ def RemoveDirectory(*path): ...@@ -251,52 +251,51 @@ def RemoveDirectory(*path):
os.rmdir(file_path) os.rmdir(file_path)
def SubprocessCall(command, in_directory, fail_status=None): def SubprocessCall(args, **kwargs):
"""Runs command, a list, in directory in_directory. """Wraps SubprocessCallAndFilter() with different default arguments.
This function wraps SubprocessCallAndFilter, but does not perform the Calls subprocess and capture nothing."""
filtering functions. See that function for a more complete usage kwargs['print_messages'] = True
description. kwargs['print_stdout'] = True
""" return SubprocessCallAndFilter(args, **kwargs)
# Call subprocess and capture nothing:
SubprocessCallAndFilter(command, in_directory, True, True, fail_status)
def SubprocessCallAndFilter(command, def SubprocessCallAndFilter(args, **kwargs):
in_directory, """Runs a command and prints a header line if appropriate.
print_messages,
print_stdout,
fail_status=None,
filter_fn=None,
stdout=None):
"""Runs command, a list, in directory in_directory.
If print_messages is true, a message indicating what is being done If |print_messages| is True, a message indicating what is being done
is printed to stdout. If print_messages is false, the message is printed is printed to stdout. Otherwise the message is printed only if the call
only if we actually need to print something else as well, so you can generated any ouput. If both |print_messages| and |print_stdout| are False,
get the context of the output. If print_messages is false and print_stdout no output at all is generated.
is false, no output at all is generated.
Also, if print_stdout is true, the command's stdout is also forwarded If |print_stdout| is True, the command's stdout is also forwarded to stdout.
to stdout.
If a filter_fn function is specified, it is expected to take a single If |filter_fn| function is specified, it is expected to take a single
string argument, and it will be called with each line of the string argument, and it will be called with each line of the
subprocess's output. Each line has had the trailing newline character subprocess's output. Each line has had the trailing newline character
trimmed. trimmed.
If the command fails, as indicated by a nonzero exit status, gclient will If the command fails, as indicated by a nonzero exit status, gclient will
exit with an exit status of fail_status. If fail_status is None (the exit with an exit status of fail_status. If fail_status is None (the
default), gclient will raise an Error exception. default), gclient will raise an Error exception.
Other subprocess.Popen parameters can be specified.
""" """
stdout = stdout or sys.stdout stdout = kwargs.pop('stdout', sys.stdout) or sys.stdout
logging.debug(command) assert not 'stderr' in kwargs
filter_fn = kwargs.pop('filter_fn', None)
print_messages = kwargs.pop('print_messages', False)
print_stdout = kwargs.pop('print_stdout', False)
fail_status = kwargs.pop('fail_status', None)
logging.debug(args)
if print_messages: if print_messages:
stdout.write('\n________ running \'%s\' in \'%s\'\n' stdout.write('\n________ running \'%s\' in \'%s\'\n'
% (' '.join(command), in_directory)) % (' '.join(args), kwargs['cwd']))
kid = Popen(command, bufsize=0, cwd=in_directory, kid = Popen(args, bufsize=0,
stdout=subprocess.PIPE, stderr=subprocess.STDOUT) stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
**kwargs)
# Do a flush of sys.stdout before we begin reading from the subprocess's # Do a flush of sys.stdout before we begin reading from the subprocess's
# stdout. # stdout.
...@@ -314,7 +313,7 @@ def SubprocessCallAndFilter(command, ...@@ -314,7 +313,7 @@ def SubprocessCallAndFilter(command,
if print_stdout: if print_stdout:
if not print_messages: if not print_messages:
stdout.write('\n________ running \'%s\' in \'%s\'\n' stdout.write('\n________ running \'%s\' in \'%s\'\n'
% (' '.join(command), in_directory)) % (' '.join(args), kwargs['cwd']))
print_messages = True print_messages = True
stdout.write(in_byte) stdout.write(in_byte)
if in_byte != '\n': if in_byte != '\n':
...@@ -337,7 +336,7 @@ def SubprocessCallAndFilter(command, ...@@ -337,7 +336,7 @@ def SubprocessCallAndFilter(command,
rv = kid.wait() rv = kid.wait()
if rv: if rv:
msg = 'failed to run command: %s' % ' '.join(command) msg = 'failed to run command: %s' % ' '.join(args)
if fail_status != None: if fail_status != None:
sys.stderr.write(msg + '\n') sys.stderr.write(msg + '\n')
sys.exit(fail_status) sys.exit(fail_status)
......
...@@ -117,38 +117,9 @@ class GIT(object): ...@@ -117,38 +117,9 @@ class GIT(object):
return results return results
@staticmethod @staticmethod
def RunAndFilterOutput(args, def RunAndFilterOutput(args, **kwargs):
in_directory, """Wrapper to gclient_utils.SubprocessCallAndFilter()."""
print_messages, return gclient_utils.SubprocessCallAndFilter([GIT.COMMAND] + args, **kwargs)
print_stdout,
filter_fn,
stdout=None):
"""Runs a command, optionally outputting to stdout.
stdout is passed line-by-line to the given filter_fn function. If
print_stdout is true, it is also printed to sys.stdout as in Run.
Args:
args: A sequence of command line parameters to be passed.
in_directory: The directory where git is to be run.
print_messages: Whether to print status messages to stdout about
which commands are being run.
print_stdout: Whether to forward program's output to stdout.
filter_fn: A function taking one argument (a string) which will be
passed each line (with the ending newline character removed) of
program's output for filtering.
Raises:
gclient_utils.Error: An error occurred while running the command.
"""
command = [GIT.COMMAND]
command.extend(args)
gclient_utils.SubprocessCallAndFilter(command,
in_directory,
print_messages,
print_stdout,
filter_fn=filter_fn,
stdout=stdout)
@staticmethod @staticmethod
def GetEmail(repo_root): def GetEmail(repo_root):
...@@ -345,20 +316,9 @@ class SVN(object): ...@@ -345,20 +316,9 @@ class SVN(object):
current_version = None current_version = None
@staticmethod @staticmethod
def Run(args, in_directory): def Run(args, **kwargs):
"""Runs svn, sending output to stdout. """Wrappers to gclient_utils.SubprocessCall()."""
return gclient_utils.SubprocessCall([SVN.COMMAND] + args, **kwargs)
Args:
args: A sequence of command line parameters to be passed to svn.
in_directory: The directory where svn is to be run.
Raises:
Error: An error occurred while running the svn command.
"""
c = [SVN.COMMAND]
c.extend(args)
# TODO(maruel): This is very gclient-specific.
gclient_utils.SubprocessCall(c, in_directory)
@staticmethod @staticmethod
def Capture(args, in_directory=None, print_error=True): def Capture(args, in_directory=None, print_error=True):
...@@ -380,7 +340,7 @@ class SVN(object): ...@@ -380,7 +340,7 @@ class SVN(object):
stderr=stderr).communicate()[0] stderr=stderr).communicate()[0]
@staticmethod @staticmethod
def RunAndGetFileList(verbose, args, in_directory, file_list, stdout=None): def RunAndGetFileList(verbose, args, cwd, file_list, stdout=None):
"""Runs svn checkout, update, or status, output to stdout. """Runs svn checkout, update, or status, output to stdout.
The first item in args must be either "checkout", "update", or "status". The first item in args must be either "checkout", "update", or "status".
...@@ -392,13 +352,12 @@ class SVN(object): ...@@ -392,13 +352,12 @@ class SVN(object):
Args: Args:
verbose: If True, uses verbose output verbose: If True, uses verbose output
args: A sequence of command line parameters to be passed to svn. args: A sequence of command line parameters to be passed to svn.
in_directory: The directory where svn is to be run. cwd: The directory where svn is to be run.
Raises: Raises:
Error: An error occurred while running the svn command. Error: An error occurred while running the svn command.
""" """
command = [SVN.COMMAND] stdout = stdout or sys.stdout
command.extend(args)
# svn update and svn checkout use the same pattern: the first three columns # svn update and svn checkout use the same pattern: the first three columns
# are for file status, property status, and lock status. This is followed # are for file status, property status, and lock status. This is followed
...@@ -434,11 +393,9 @@ class SVN(object): ...@@ -434,11 +393,9 @@ class SVN(object):
failure.append(line) failure.append(line)
try: try:
SVN.RunAndFilterOutput(args, SVN.RunAndFilterOutput(args, cwd=cwd, print_messages=verbose,
in_directory, print_stdout=True,
verbose, filter_fn=CaptureMatchingLines,
True,
CaptureMatchingLines,
stdout=stdout) stdout=stdout)
except gclient_utils.Error: except gclient_utils.Error:
def IsKnownFailure(): def IsKnownFailure():
...@@ -481,38 +438,9 @@ class SVN(object): ...@@ -481,38 +438,9 @@ class SVN(object):
break break
@staticmethod @staticmethod
def RunAndFilterOutput(args, def RunAndFilterOutput(args, **kwargs):
in_directory, """Wrapper for gclient_utils.SubprocessCallAndFilter()."""
print_messages, return gclient_utils.SubprocessCallAndFilter([SVN.COMMAND] + args, **kwargs)
print_stdout,
filter_fn,
stdout=None):
"""Runs a command, optionally outputting to stdout.
stdout is passed line-by-line to the given filter_fn function. If
print_stdout is true, it is also printed to sys.stdout as in Run.
Args:
args: A sequence of command line parameters to be passed.
in_directory: The directory where svn is to be run.
print_messages: Whether to print status messages to stdout about
which commands are being run.
print_stdout: Whether to forward program's output to stdout.
filter_fn: A function taking one argument (a string) which will be
passed each line (with the ending newline character removed) of
program's output for filtering.
Raises:
gclient_utils.Error: An error occurred while running the command.
"""
command = [SVN.COMMAND]
command.extend(args)
gclient_utils.SubprocessCallAndFilter(command,
in_directory,
print_messages,
print_stdout,
filter_fn=filter_fn,
stdout=stdout)
@staticmethod @staticmethod
def CaptureInfo(relpath, in_directory=None, print_error=True): def CaptureInfo(relpath, in_directory=None, print_error=True):
......
...@@ -43,6 +43,7 @@ class BaseTestCase(GCBaseTestCase): ...@@ -43,6 +43,7 @@ class BaseTestCase(GCBaseTestCase):
self.mox.StubOutWithMock(gclient_scm.scm.SVN, 'Run') self.mox.StubOutWithMock(gclient_scm.scm.SVN, 'Run')
self.mox.StubOutWithMock(gclient_scm.scm.SVN, 'RunAndGetFileList') self.mox.StubOutWithMock(gclient_scm.scm.SVN, 'RunAndGetFileList')
self._scm_wrapper = gclient_scm.CreateSCM self._scm_wrapper = gclient_scm.CreateSCM
gclient_scm.sys.stdout.flush = lambda: None
class SVNWrapperTestCase(BaseTestCase): class SVNWrapperTestCase(BaseTestCase):
...@@ -68,7 +69,7 @@ class SVNWrapperTestCase(BaseTestCase): ...@@ -68,7 +69,7 @@ class SVNWrapperTestCase(BaseTestCase):
def testDir(self): def testDir(self):
members = [ members = [
'AddAdditionalFlags', 'FullUrlForRelativeUrl', 'RunCommand', 'FullUrlForRelativeUrl', 'RunCommand',
'cleanup', 'diff', 'export', 'pack', 'relpath', 'revert', 'cleanup', 'diff', 'export', 'pack', 'relpath', 'revert',
'revinfo', 'runhooks', 'status', 'update', 'revinfo', 'runhooks', 'status', 'update',
'updatesingle', 'url', 'updatesingle', 'url',
...@@ -118,6 +119,8 @@ class SVNWrapperTestCase(BaseTestCase): ...@@ -118,6 +119,8 @@ class SVNWrapperTestCase(BaseTestCase):
options = self.Options(verbose=True) options = self.Options(verbose=True)
base_path = gclient_scm.os.path.join(self.root_dir, self.relpath) base_path = gclient_scm.os.path.join(self.root_dir, self.relpath)
gclient_scm.os.path.isdir(base_path).AndReturn(False) gclient_scm.os.path.isdir(base_path).AndReturn(False)
gclient_scm.scm.SVN.Capture(['--version']
).AndReturn('svn, version 1.5.1 (r32289)')
# It'll to a checkout instead. # It'll to a checkout instead.
gclient_scm.os.path.exists(gclient_scm.os.path.join(base_path, '.git') gclient_scm.os.path.exists(gclient_scm.os.path.join(base_path, '.git')
).AndReturn(False) ).AndReturn(False)
...@@ -126,7 +129,8 @@ class SVNWrapperTestCase(BaseTestCase): ...@@ -126,7 +129,8 @@ class SVNWrapperTestCase(BaseTestCase):
gclient_scm.os.path.exists(base_path).AndReturn(False) gclient_scm.os.path.exists(base_path).AndReturn(False)
files_list = self.mox.CreateMockAnything() files_list = self.mox.CreateMockAnything()
gclient_scm.scm.SVN.RunAndGetFileList(options.verbose, gclient_scm.scm.SVN.RunAndGetFileList(options.verbose,
['checkout', self.url, base_path], ['checkout', self.url, base_path,
'--force'],
self.root_dir, files_list) self.root_dir, files_list)
self.mox.ReplayAll() self.mox.ReplayAll()
...@@ -235,7 +239,8 @@ class SVNWrapperTestCase(BaseTestCase): ...@@ -235,7 +239,8 @@ class SVNWrapperTestCase(BaseTestCase):
gclient_scm.os.path.exists(base_path).AndReturn(False) gclient_scm.os.path.exists(base_path).AndReturn(False)
files_list = self.mox.CreateMockAnything() files_list = self.mox.CreateMockAnything()
gclient_scm.scm.SVN.RunAndGetFileList(options.verbose, gclient_scm.scm.SVN.RunAndGetFileList(options.verbose,
['checkout', self.url, base_path], ['checkout', self.url, base_path,
'--force'],
self.root_dir, files_list) self.root_dir, files_list)
self.mox.ReplayAll() self.mox.ReplayAll()
scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir, scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
...@@ -307,7 +312,8 @@ class SVNWrapperTestCase(BaseTestCase): ...@@ -307,7 +312,8 @@ class SVNWrapperTestCase(BaseTestCase):
# When checking out a single file, we issue an svn checkout and svn update. # When checking out a single file, we issue an svn checkout and svn update.
files_list = self.mox.CreateMockAnything() files_list = self.mox.CreateMockAnything()
gclient_scm.scm.SVN.Run( gclient_scm.scm.SVN.Run(
['checkout', '--depth', 'empty', self.url, base_path], self.root_dir) ['checkout', '--depth', 'empty', self.url, base_path],
cwd=self.root_dir)
gclient_scm.scm.SVN.RunAndGetFileList(options.verbose, ['update', 'DEPS'], gclient_scm.scm.SVN.RunAndGetFileList(options.verbose, ['update', 'DEPS'],
gclient_scm.os.path.join(self.root_dir, self.relpath), files_list) gclient_scm.os.path.join(self.root_dir, self.relpath), files_list)
...@@ -345,7 +351,8 @@ class SVNWrapperTestCase(BaseTestCase): ...@@ -345,7 +351,8 @@ class SVNWrapperTestCase(BaseTestCase):
files_list = self.mox.CreateMockAnything() files_list = self.mox.CreateMockAnything()
gclient_scm.scm.SVN.Run( gclient_scm.scm.SVN.Run(
['export', gclient_scm.os.path.join(self.url, 'DEPS'), ['export', gclient_scm.os.path.join(self.url, 'DEPS'),
gclient_scm.os.path.join(base_path, 'DEPS')], self.root_dir) gclient_scm.os.path.join(base_path, 'DEPS')],
cwd=self.root_dir)
self.mox.ReplayAll() self.mox.ReplayAll()
scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir, scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
...@@ -379,7 +386,8 @@ class SVNWrapperTestCase(BaseTestCase): ...@@ -379,7 +386,8 @@ class SVNWrapperTestCase(BaseTestCase):
# When checking out a single file, we issue an svn checkout and svn update. # When checking out a single file, we issue an svn checkout and svn update.
files_list = self.mox.CreateMockAnything() files_list = self.mox.CreateMockAnything()
gclient_scm.scm.SVN.Run( gclient_scm.scm.SVN.Run(
['checkout', '--depth', 'empty', self.url, base_path], self.root_dir) ['checkout', '--depth', 'empty', self.url, base_path],
cwd=self.root_dir)
gclient_scm.scm.SVN.RunAndGetFileList(options.verbose, ['update', 'DEPS'], gclient_scm.scm.SVN.RunAndGetFileList(options.verbose, ['update', 'DEPS'],
gclient_scm.os.path.join(self.root_dir, self.relpath), files_list) gclient_scm.os.path.join(self.root_dir, self.relpath), files_list)
......
...@@ -37,29 +37,29 @@ class GclientUtilsUnittest(GclientUtilBase): ...@@ -37,29 +37,29 @@ class GclientUtilsUnittest(GclientUtilBase):
class CheckCallTestCase(GclientUtilBase): class CheckCallTestCase(GclientUtilBase):
def testCheckCallSuccess(self): def testCheckCallSuccess(self):
command = ['boo', 'foo', 'bar'] args = ['boo', 'foo', 'bar']
process = self.mox.CreateMockAnything() process = self.mox.CreateMockAnything()
process.returncode = 0 process.returncode = 0
env = gclient_utils.os.environ.copy() env = gclient_utils.os.environ.copy()
env['LANGUAGE'] = 'en' env['LANGUAGE'] = 'en'
gclient_utils.subprocess.Popen( gclient_utils.subprocess.Popen(
command, cwd=None, args, cwd=None,
stderr=None, stderr=None,
env=env, env=env,
stdout=gclient_utils.subprocess.PIPE, stdout=gclient_utils.subprocess.PIPE,
shell=gclient_utils.sys.platform.startswith('win')).AndReturn(process) shell=gclient_utils.sys.platform.startswith('win')).AndReturn(process)
process.communicate().AndReturn(['bleh', 'foo']) process.communicate().AndReturn(['bleh', 'foo'])
self.mox.ReplayAll() self.mox.ReplayAll()
gclient_utils.CheckCall(command) gclient_utils.CheckCall(args)
def testCheckCallFailure(self): def testCheckCallFailure(self):
command = ['boo', 'foo', 'bar'] args = ['boo', 'foo', 'bar']
process = self.mox.CreateMockAnything() process = self.mox.CreateMockAnything()
process.returncode = 42 process.returncode = 42
env = gclient_utils.os.environ.copy() env = gclient_utils.os.environ.copy()
env['LANGUAGE'] = 'en' env['LANGUAGE'] = 'en'
gclient_utils.subprocess.Popen( gclient_utils.subprocess.Popen(
command, cwd=None, args, cwd=None,
stderr=None, stderr=None,
env=env, env=env,
stdout=gclient_utils.subprocess.PIPE, stdout=gclient_utils.subprocess.PIPE,
...@@ -67,10 +67,10 @@ class CheckCallTestCase(GclientUtilBase): ...@@ -67,10 +67,10 @@ class CheckCallTestCase(GclientUtilBase):
process.communicate().AndReturn(['bleh', 'foo']) process.communicate().AndReturn(['bleh', 'foo'])
self.mox.ReplayAll() self.mox.ReplayAll()
try: try:
gclient_utils.CheckCall(command) gclient_utils.CheckCall(args)
self.fail() self.fail()
except gclient_utils.CheckCallError, e: except gclient_utils.CheckCallError, e:
self.assertEqual(e.command, command) self.assertEqual(e.command, args)
self.assertEqual(e.cwd, None) self.assertEqual(e.cwd, None)
self.assertEqual(e.retcode, 42) self.assertEqual(e.retcode, 42)
self.assertEqual(e.stdout, 'bleh') self.assertEqual(e.stdout, 'bleh')
...@@ -84,8 +84,8 @@ class SubprocessCallAndFilterTestCase(GclientUtilBase): ...@@ -84,8 +84,8 @@ class SubprocessCallAndFilterTestCase(GclientUtilBase):
def wait(self): def wait(self):
pass pass
def _inner(self, command, test_string): def _inner(self, args, test_string):
in_directory = 'bleh' cwd = 'bleh'
env = gclient_utils.os.environ.copy() env = gclient_utils.os.environ.copy()
env['LANGUAGE'] = 'en' env['LANGUAGE'] = 'en'
gclient_utils.sys.stdout.write( gclient_utils.sys.stdout.write(
...@@ -93,8 +93,8 @@ class SubprocessCallAndFilterTestCase(GclientUtilBase): ...@@ -93,8 +93,8 @@ class SubprocessCallAndFilterTestCase(GclientUtilBase):
for i in test_string: for i in test_string:
gclient_utils.sys.stdout.write(i) gclient_utils.sys.stdout.write(i)
gclient_utils.subprocess.Popen( gclient_utils.subprocess.Popen(
command, args,
cwd=in_directory, cwd=cwd,
shell=(gclient_utils.sys.platform == 'win32'), shell=(gclient_utils.sys.platform == 'win32'),
env=env, env=env,
stdout=gclient_utils.subprocess.PIPE, stdout=gclient_utils.subprocess.PIPE,
...@@ -111,20 +111,21 @@ class SubprocessCallAndFilterTestCase(GclientUtilBase): ...@@ -111,20 +111,21 @@ class SubprocessCallAndFilterTestCase(GclientUtilBase):
if match: if match:
capture_list.append(match.group(1)) capture_list.append(match.group(1))
gclient_utils.SubprocessCallAndFilter( gclient_utils.SubprocessCallAndFilter(
command, in_directory, True, True, None, FilterLines) args, cwd=cwd, print_messages=True, print_stdout=True,
filter_fn=FilterLines)
self.assertEquals(line_list, ['ahah', 'accb', 'allo', 'addb']) self.assertEquals(line_list, ['ahah', 'accb', 'allo', 'addb'])
self.assertEquals(capture_list, ['cc', 'dd']) self.assertEquals(capture_list, ['cc', 'dd'])
def testSubprocessCallAndFilter(self): def testSubprocessCallAndFilter(self):
command = ['boo', 'foo', 'bar'] args = ['boo', 'foo', 'bar']
test_string = 'ahah\naccb\nallo\naddb\n' test_string = 'ahah\naccb\nallo\naddb\n'
self._inner(command, test_string) self._inner(args, test_string)
def testNoLF(self): def testNoLF(self):
# Exactly as testSubprocessCallAndFilter without trailing \n # Exactly as testSubprocessCallAndFilter without trailing \n
command = ['boo', 'foo', 'bar'] args = ['boo', 'foo', 'bar']
test_string = 'ahah\naccb\nallo\naddb' test_string = 'ahah\naccb\nallo\naddb'
self._inner(command, test_string) self._inner(args, test_string)
class SplitUrlRevisionTestCase(GclientUtilBase): class SplitUrlRevisionTestCase(GclientUtilBase):
......
...@@ -316,9 +316,9 @@ class SVNTestCase(BaseSCMTestCase): ...@@ -316,9 +316,9 @@ class SVNTestCase(BaseSCMTestCase):
def testRun(self): def testRun(self):
param2 = 'bleh' param2 = 'bleh'
scm.gclient_utils.SubprocessCall(['svn', 'foo', 'bar'], scm.gclient_utils.SubprocessCall(['svn', 'foo', 'bar'],
param2).AndReturn(None) cwd=param2).AndReturn(None)
self.mox.ReplayAll() self.mox.ReplayAll()
scm.SVN.Run(['foo', 'bar'], param2) scm.SVN.Run(['foo', 'bar'], cwd=param2)
def testCaptureStatusEmpty(self): def testCaptureStatusEmpty(self):
text = r"""<?xml version="1.0"?> text = r"""<?xml version="1.0"?>
......
...@@ -97,6 +97,7 @@ class SCM(object): ...@@ -97,6 +97,7 @@ class SCM(object):
self.options.files = None self.options.files = None
self.codereview_settings = None self.codereview_settings = None
self.codereview_settings_file = 'codereview.settings' self.codereview_settings_file = 'codereview.settings'
self.gclient_root = None
def GetFileNames(self): def GetFileNames(self):
"""Return the list of files in the diff.""" """Return the list of files in the diff."""
...@@ -136,7 +137,6 @@ class SCM(object): ...@@ -136,7 +137,6 @@ class SCM(object):
def _GclientStyleSettings(self): def _GclientStyleSettings(self):
"""Find the root, assuming a gclient-style checkout.""" """Find the root, assuming a gclient-style checkout."""
self.gclient_root = None
if not self.options.no_gclient and not self.options.root: if not self.options.no_gclient and not self.options.root:
root = self.checkout_root root = self.checkout_root
self.gclient_root = gclient_utils.FindGclientRoot(root) self.gclient_root = gclient_utils.FindGclientRoot(root)
...@@ -301,7 +301,7 @@ def _SendChangeHTTP(options): ...@@ -301,7 +301,7 @@ def _SendChangeHTTP(options):
'server port to connect to.') 'server port to connect to.')
values = _ParseSendChangeOptions(options) values = _ParseSendChangeOptions(options)
description = ''.join("%s=%s\n" % (k,v) for (k,v) in values.iteritems()) description = ''.join("%s=%s\n" % (k, v) for (k, v) in values.iteritems())
values['patch'] = options.diff values['patch'] = options.diff
url = 'http://%s:%s/send_try_patch' % (options.host, options.port) url = 'http://%s:%s/send_try_patch' % (options.host, options.port)
...@@ -345,7 +345,7 @@ def _SendChangeSVN(options): ...@@ -345,7 +345,7 @@ def _SendChangeSVN(options):
' try server svn repository to connect to.') ' try server svn repository to connect to.')
values = _ParseSendChangeOptions(options) values = _ParseSendChangeOptions(options)
description = ''.join("%s=%s\n" % (k,v) for (k,v) in values.iteritems()) description = ''.join("%s=%s\n" % (k, v) for (k, v) in values.iteritems())
logging.info('Sending by SVN') logging.info('Sending by SVN')
logging.info(description) logging.info(description)
logging.info(options.svn_repo) logging.info(options.svn_repo)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment