Commit 096469fa authored by maruel@chromium.org's avatar maruel@chromium.org

Enable automatic command and one-liner doc. Reformat pydoc accordingly.

Add parser as an argument and parse_args hook in preparation to move parse_args at the right place, inside the CMDxx functions.

R.I.P. gclient_test.py

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

git-svn-id: svn://svn.chromium.org/chrome/trunk/tools/depot_tools@48271 0039d316-1c4b-4281-b951-d872f2087c98
parent 3eac7057
......@@ -10,7 +10,6 @@ details on the presubmit API built into gcl.
UNIT_TESTS = [
'tests.gcl_unittest',
'tests.gclient_test',
'tests.gclient_scm_test',
'tests.gclient_utils_test',
'tests.presubmit_unittest',
......
......@@ -55,7 +55,7 @@ Hooks
]
"""
__version__ = "0.3.7"
__version__ = "0.4"
import errno
import logging
......@@ -73,22 +73,6 @@ import gclient_scm
import gclient_utils
from third_party.repo.progress import Progress
# default help text
DEFAULT_USAGE_TEXT = (
"""%prog <subcommand> [options] [--] [SCM options/args...]
a wrapper for managing a set of svn client modules and/or git repositories.
Version """ + __version__ + """
Options and extra arguments can be passed to invoked SCM commands by
appending them to the command line. Note that if the first such
appended option starts with a dash (-) then the options must be
preceded by -- to distinguish them from gclient options.
For additional help on a subcommand or examples of usage, try
%prog help <subcommand>
%prog help files
""")
def attr(attr, data):
"""Sets an attribute on a function."""
......@@ -813,19 +797,15 @@ solutions = [
print(snapclient._config_content)
## gclient commands.
#### gclient commands.
def CMDcleanup(parser, options, args):
"""Clean up all working copies, using 'svn cleanup' for each module.
Additional options and args may be passed to 'svn cleanup'.
def CMDcleanup(parser, args):
"""Cleans up all working copies.
usage: cleanup [options] [--] [svn cleanup args/options]
Valid options:
--verbose : output additional diagnostics
Mostly svn-specific. Simply runs 'svn cleanup' for each module.
"""
(options, args) = parser.parse_args(args)
client = GClient.LoadCurrentConfig(options)
if not client:
raise gclient_utils.Error("client not configured; see 'gclient config'")
......@@ -836,32 +816,23 @@ Valid options:
return client.RunOnDeps('cleanup', args)
def CMDconfig(parser, options, args):
@attr('usage', '[url] [safesync url]')
def CMDconfig(parser, args):
"""Create a .gclient file in the current directory.
This specifies the configuration for further commands. After update/sync,
This specifies the configuration for further commands. After update/sync,
top-level DEPS files in each module are read to determine dependent
modules to operate on as well. If optional [url] parameter is
modules to operate on as well. If optional [url] parameter is
provided, then configuration is read from a specified Subversion server
URL. Otherwise, a --spec option must be provided. A --name option overrides
the default name for the solutions.
usage: config [option | url] [safesync url]
Valid options:
--name path : alternate relative path for the solution
--spec=GCLIENT_SPEC : contents of .gclient are read from string parameter.
*Note that due to Cygwin/Python brokenness, it
probably can't contain any newlines.*
Examples:
gclient config https://gclient.googlecode.com/svn/trunk/gclient
configure a new client to check out gclient.py tool sources
gclient config --name tools https://gclient.googlecode.com/svn/trunk/gclient
gclient config --spec='solutions=[{"name":"gclient",
'"url":"https://gclient.googlecode.com/svn/trunk/gclient",'
'"custom_deps":{}}]'
URL.
"""
parser.add_option("--spec",
help="create a gclient file containing the provided "
"string. Due to Cygwin/Python brokenness, it "
"probably can't contain any newlines.")
parser.add_option("--name",
help="overrides the default name for the solution")
(options, args) = parser.parse_args(args)
if len(args) < 1 and not options.spec:
raise gclient_utils.Error("required argument missing; see 'gclient help "
"config'")
......@@ -886,8 +857,9 @@ Examples:
return 0
def CMDexport(parser, options, args):
def CMDexport(parser, args):
"""Wrapper for svn export for all managed directories."""
(options, args) = parser.parse_args(args)
if len(args) != 1:
raise gclient_utils.Error("Need directory name")
client = GClient.LoadCurrentConfig(options)
......@@ -902,30 +874,19 @@ def CMDexport(parser, options, args):
return client.RunOnDeps('export', args)
def CMDpack(parser, options, args):
@attr('epilog', """Example:
gclient pack > patch.txt
generate simple patch for configured client and dependences
""")
def CMDpack(parser, args):
"""Generate a patch which can be applied at the root of the tree.
Internally, runs 'svn diff' on each checked out module and
Internally, runs 'svn diff'/'git diff' on each checked out module and
dependencies, and performs minimal postprocessing of the output. The
resulting patch is printed to stdout and can be applied to a freshly
checked out tree via 'patch -p0 < patchfile'. Additional args and
options to 'svn diff' can be passed after gclient options.
usage: pack [options] [--] [svn args/options]
Valid options:
--verbose : output additional diagnostics
Examples:
gclient pack > patch.txt
generate simple patch for configured client and dependences
gclient pack -- -x -b > patch.txt
generate patch using 'svn diff -x -b' to suppress
whitespace-only differences
gclient pack -- -r HEAD -x -b > patch.txt
generate patch, diffing each file versus the latest version of
each module
checked out tree via 'patch -p0 < patchfile'.
"""
(options, args) = parser.parse_args(args)
client = GClient.LoadCurrentConfig(options)
if not client:
raise gclient_utils.Error("client not configured; see 'gclient config'")
......@@ -936,17 +897,9 @@ Examples:
return client.RunOnDeps('pack', args)
def CMDstatus(parser, options, args):
"""Show the modification status of for every dependencies.
Additional options and args may be passed to 'svn status'.
usage: status [options] [--] [svn diff args/options]
Valid options:
--verbose : output additional diagnostics
--nohooks : don't run the hooks after the update is complete
"""
def CMDstatus(parser, args):
"""Show modification status for every dependencies."""
(options, args) = parser.parse_args(args)
client = GClient.LoadCurrentConfig(options)
if not client:
raise gclient_utils.Error("client not configured; see 'gclient config'")
......@@ -957,31 +910,7 @@ Valid options:
return client.RunOnDeps('status', args)
def CMDsync(parser, options, args):
"""Checkout/update the modules specified by the gclient configuration.
Unless --revision is specified, then the latest revision of the root solutions
is checked out, with dependent submodule versions updated according to DEPS
files. If --revision is specified, then the given revision is used in place
of the latest, either for a single solution or for all solutions.
Unless the --force option is provided, solutions and modules whose
local revision matches the one to update (i.e., they have not changed
in the repository) are *not* modified. Unless --nohooks is provided,
the hooks are run. See 'help config' for more information.
usage: gclient sync [options] [--] [SCM update options/args]
Valid options:
--force : force update even for unchanged modules
--nohooks : don't run the hooks after the update is complete
--revision SOLUTION@REV : update given solution to specified revision
--deps PLATFORM(S) : sync deps for the given platform(s), or 'all'
--verbose : output additional diagnostics
--head : update to latest revision, instead of last good
revision
--reset : resets any local changes before updating (git only)
Examples:
@attr('epilog', """Examples:
gclient sync
update files from SCM according to current configuration,
*for modules which have changed since last update or sync*
......@@ -990,7 +919,33 @@ Examples:
all modules (useful for recovering files deleted from local copy)
gclient sync --revision src@31000
update src directory to r31000
"""
""")
def CMDsync(parser, args):
"""Checkout/update all modules."""
parser.add_option("--force", action="store_true",
help="force update even for unchanged modules")
parser.add_option("--nohooks", action="store_true",
help="don't run hooks after the update is complete")
parser.add_option("-r", "--revision", action="append",
dest="revisions", metavar="REV", default=[],
help="update given solution to specified revision, "
"can be used multiple times for each solution, "
"e.g. -r src@123, -r internal@32")
parser.add_option("--head", action="store_true",
help="skips any safesync_urls specified in "
"configured solutions and sync to head instead")
parser.add_option("--delete_unversioned_trees", action="store_true",
help="delete any unexpected unversioned trees "
"that are in the checkout")
parser.add_option("--reset", action="store_true",
help="resets any local changes before updating (git only)")
parser.add_option("--deps", dest="deps_os", metavar="OS_LIST",
help="sync deps for the specified (comma-separated) "
"platform(s); 'all' will sync all platforms")
parser.add_option("--manually_grab_svn_rev", action="store_true",
help="Skip svn up whenever possible by requesting "
"actual HEAD revision from the repository")
(options, args) = parser.parse_args(args)
client = GClient.LoadCurrentConfig(options)
if not client:
......@@ -1023,31 +978,13 @@ Examples:
return client.RunOnDeps('update', args)
def CMDupdate(parser, options, args):
def CMDupdate(parser, args):
"""Alias for the sync command. Deprecated."""
return CMDsync(parser, options, args)
def CMDdiff(parser, options, args):
"""Display the differences between two revisions of modules.
return CMDsync(parser, args)
(Does 'svn diff' for each checked out module and dependences.)
Additional args and options to 'svn diff' can be passed after
gclient options.
usage: diff [options] [--] [svn args/options]
Valid options:
--verbose : output additional diagnostics
Examples:
gclient diff
simple 'svn diff' for configured client and dependences
gclient diff -- -x -b
use 'svn diff -x -b' to suppress whitespace-only differences
gclient diff -- -r HEAD -x -b
diff versus the latest version of each module
"""
def CMDdiff(parser, args):
"""Displays local diff for every dependencies."""
(options, args) = parser.parse_args(args)
client = GClient.LoadCurrentConfig(options)
if not client:
raise gclient_utils.Error("client not configured; see 'gclient config'")
......@@ -1058,24 +995,24 @@ Examples:
return client.RunOnDeps('diff', args)
def CMDrevert(parser, options, args):
"""Revert every file in every managed directory in the client view."""
def CMDrevert(parser, args):
"""Revert all modifications in every dependencies."""
parser.add_option("--nohooks", action="store_true",
help="don't run hooks after the revert is complete")
(options, args) = parser.parse_args(args)
# --force is implied.
options.force = True
client = GClient.LoadCurrentConfig(options)
if not client:
raise gclient_utils.Error("client not configured; see 'gclient config'")
return client.RunOnDeps('revert', args)
def CMDrunhooks(parser, options, args):
"""Runs hooks for files that have been modified in the local working copy.
Implies --force.
usage: runhooks [options]
Valid options:
--verbose : output additional diagnostics
"""
def CMDrunhooks(parser, args):
"""Runs hooks for files that have been modified in the local working copy."""
parser.add_option("--force", action="store_true", default=True,
help="Deprecated. No effect.")
(options, args) = parser.parse_args(args)
client = GClient.LoadCurrentConfig(options)
if not client:
raise gclient_utils.Error("client not configured; see 'gclient config'")
......@@ -1087,15 +1024,12 @@ Valid options:
return client.RunOnDeps('runhooks', args)
def CMDrevinfo(parser, options, args):
"""Outputs defails for every dependencies.
This includes source path, server URL and revision information for every
dependency in all solutions.
usage: revinfo [options]
"""
__pychecker__ = 'unusednames=args'
def CMDrevinfo(parser, args):
"""Outputs details for every dependencies."""
parser.add_option("--snapshot", action="store_true",
help="create a snapshot file of the current "
"version of all repositories")
(options, args) = parser.parse_args(args)
client = GClient.LoadCurrentConfig(options)
if not client:
raise gclient_utils.Error("client not configured; see 'gclient config'")
......@@ -1103,70 +1037,45 @@ usage: revinfo [options]
return 0
def CMDhelp(parser, options, args):
"""Prints general help or command-specific documentation."""
def Command(name):
return getattr(sys.modules[__name__], 'CMD' + name, None)
def CMDhelp(parser, args):
"""Prints list of commands or help for a specific command."""
(options, args) = parser.parse_args(args)
if len(args) == 1:
command = Command(args[0])
if command:
print getattr(sys.modules[__name__], 'CMD' + args[0]).__doc__
return 0
parser.usage = (DEFAULT_USAGE_TEXT + '\nCommands are:\n' + '\n'.join([
' %-10s %s' % (fn[3:], Command(fn[3:]).__doc__.split('\n')[0].strip())
for fn in dir(sys.modules[__name__]) if fn.startswith('CMD')]))
return Main(args + ['--help'])
parser.print_help()
return 0
def Command(command):
return getattr(sys.modules[__name__], 'CMD' + command, CMDhelp)
def GenUsage(parser, command):
"""Modify an OptParse object with the function's documentation."""
obj = Command(command)
if command == 'help':
command = '<command>'
# OptParser.description prefer nicely non-formatted strings.
parser.description = re.sub('[\r\n ]{2,}', ' ', obj.__doc__)
usage = getattr(obj, 'usage', '')
parser.set_usage('%%prog %s [options] %s' % (command, usage))
parser.epilog = getattr(obj, 'epilog', None)
def Main(argv):
parser = optparse.OptionParser(usage=DEFAULT_USAGE_TEXT,
version='%prog ' + __version__)
"""Doesn't parse the arguments here, just find the right subcommand to
execute."""
# Do it late so all commands are listed.
CMDhelp.usage = ('\n\nCommands are:\n' + '\n'.join([
' %-10s %s' % (fn[3:], Command(fn[3:]).__doc__.split('\n')[0].strip())
for fn in dir(sys.modules[__name__]) if fn.startswith('CMD')]))
parser = optparse.OptionParser(version='%prog ' + __version__)
parser.add_option("-v", "--verbose", action="count", default=0,
help="Produces additional output for diagnostics. Can be "
"used up to three times for more logging info.")
parser.add_option("--gclientfile", metavar="FILENAME", dest="config_filename",
default=os.environ.get("GCLIENT_FILE", ".gclient"),
help="Specify an alternate .gclient file")
# The other options will be moved eventually.
parser.add_option("--force", action="store_true",
help="(update/sync only) force update even "
"for modules which haven't changed")
parser.add_option("--nohooks", action="store_true",
help="(update/sync/revert only) prevent the hooks "
"from running")
parser.add_option("--revision", action="append", dest="revisions",
metavar="REV", default=[],
help="(update/sync only) sync to a specific "
"revision, can be used multiple times for "
"each solution, e.g. --revision=src@123, "
"--revision=internal@32")
parser.add_option("--deps", dest="deps_os", metavar="OS_LIST",
help="(update/sync only) sync deps for the "
"specified (comma-separated) platform(s); "
"'all' will sync all platforms")
parser.add_option("--reset", action="store_true",
help="(update/sync only) resets any local changes "
"before updating (git only)")
parser.add_option("--spec",
help="(config only) create a gclient file "
"containing the provided string")
parser.add_option("--manually_grab_svn_rev", action="store_true",
help="Skip svn up whenever possible by requesting "
"actual HEAD revision from the repository")
parser.add_option("--head", action="store_true",
help="skips any safesync_urls specified in "
"configured solutions")
parser.add_option("--delete_unversioned_trees", action="store_true",
help="on update, delete any unexpected "
"unversioned trees that are in the checkout")
parser.add_option("--snapshot", action="store_true",
help="(revinfo only), create a snapshot file "
"of the current version of all repositories")
parser.add_option("--name",
help="specify alternate relative solution path")
# Integrate standard options processing.
old_parser = parser.parse_args
def Parse(args):
......@@ -1176,22 +1085,22 @@ def Main(argv):
elif options.verbose > 2:
logging.basicConfig(level=logging.DEBUG)
options.entries_filename = options.config_filename + "_entries"
if not hasattr(options, 'revisions'):
# GClient.RunOnDeps expects it even if not applicable.
options.revisions = []
return (options, args)
parser.parse_args = Parse
# We don't want wordwrapping in epilog (usually examples)
parser.format_epilog = lambda _: parser.epilog or ''
if not len(argv):
argv = ['help']
# Add manual support for --version as first argument.
if argv[0] == '--version':
parser.print_version()
return 0
# Add manual support for --help as first argument.
if argv[0] == '--help':
argv[0] = 'help'
options, args = parser.parse_args(argv[1:])
return Command(argv[0])(parser, options, args)
if argv:
command = Command(argv[0])
if command:
# "fix" the usage and the description now that we know the subcommand.
GenUsage(parser, argv[0])
return command(parser, argv[1:])
# Not a known command. Default to help.
GenUsage(parser, 'help')
return CMDhelp(parser, argv)
if "__main__" == __name__:
......
......@@ -131,7 +131,7 @@ class GClientSmoke(GClientSmokeBase):
def testCommands(self):
"""This test is to make sure no new command was added."""
result = self.gclient(['help'])
self.assertEquals(3189, len(result[0]))
self.assertEquals(1197, len(result[0]))
self.assertEquals(0, len(result[1]))
self.assertEquals(0, result[2])
......
#!/usr/bin/python
# Copyright (c) 2010 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Unit tests for gclient.py."""
# Fixes include path.
from super_mox import mox, SuperMoxTestBase
import gclient
class BaseTestCase(SuperMoxTestBase):
# Like unittest's assertRaises, but checks for Gclient.Error.
def assertRaisesError(self, msg, fn, *args, **kwargs):
try:
fn(*args, **kwargs)
except gclient.gclient_utils.Error, e:
self.assertEquals(e.args[0], msg)
else:
self.fail('%s not raised' % msg)
class GClientBaseTestCase(BaseTestCase):
def Options(self, *args, **kwargs):
return self.OptionsObject(self, *args, **kwargs)
def setUp(self):
BaseTestCase.setUp(self)
# These are not tested.
self.mox.StubOutWithMock(gclient.gclient_utils, 'FileRead')
self.mox.StubOutWithMock(gclient.gclient_utils, 'FileWrite')
self.mox.StubOutWithMock(gclient.gclient_utils, 'SubprocessCall')
self.mox.StubOutWithMock(gclient.gclient_utils, 'RemoveDirectory')
# Mock them to be sure nothing bad happens.
self.mox.StubOutWithMock(gclient.gclient_scm.scm.SVN, 'Capture')
self.mox.StubOutWithMock(gclient.gclient_scm.scm.SVN, 'CaptureInfo')
self.mox.StubOutWithMock(gclient.gclient_scm.scm.SVN, 'CaptureStatus')
self.mox.StubOutWithMock(gclient.gclient_scm.scm.SVN, 'Run')
self.mox.StubOutWithMock(gclient.gclient_scm.scm.SVN, 'RunAndGetFileList')
self._gclient_gclient = gclient.GClient
gclient.GClient = self.mox.CreateMockAnything()
gclient.GClient.DEPS_FILE = self._gclient_gclient.DEPS_FILE
gclient.GClient.DEFAULT_CLIENT_FILE_TEXT = (
self._gclient_gclient.DEFAULT_CLIENT_FILE_TEXT)
self._scm_wrapper = gclient.gclient_scm.CreateSCM
gclient.gclient_scm.CreateSCM = self.mox.CreateMockAnything()
def tearDown(self):
gclient.GClient = self._gclient_gclient
gclient.gclient_scm.CreateSCM = self._scm_wrapper
BaseTestCase.tearDown(self)
class GclientTestCase(GClientBaseTestCase):
class OptionsObject(object):
def __init__(self, test_case, verbose=0, spec=None,
config_filename='a_file_name',
entries_filename='a_entry_file_name',
force=False, nohooks=False):
self.verbose = verbose
self.config_filename = config_filename
self.entries_filename = entries_filename
self.spec = spec
self.name = None
self.force = force
self.nohooks = nohooks
self.revisions = []
self.manually_grab_svn_rev = True
self.deps_os = None
self.head = False
def setUp(self):
GClientBaseTestCase.setUp(self)
self.args = self.Args()
self.root_dir = self.Dir()
self.url = self.Url()
class GClientCommandsTestCase(GClientBaseTestCase):
def testCommands(self):
known_commands = [gclient.CMDcleanup, gclient.CMDconfig, gclient.CMDdiff,
gclient.CMDexport, gclient.CMDhelp, gclient.CMDpack,
gclient.CMDrevert, gclient.CMDrevinfo,
gclient.CMDrunhooks, gclient.CMDstatus, gclient.CMDsync,
gclient.CMDupdate]
cmds = [getattr(gclient, x) for x in dir(gclient) if x.startswith('CMD')]
self.assertEquals(len(known_commands), len(cmds))
for v in cmds:
# If it fails, you need to add a test case for the new command.
self.assert_(v in known_commands)
self.mox.ReplayAll()
class TestCMDconfig(GclientTestCase):
def testMissingArgument(self):
exception_msg = "required argument missing; see 'gclient help config'"
self.mox.ReplayAll()
self.assertRaisesError(exception_msg, gclient.CMDconfig, None,
self.Options(), ())
def testExistingClientFile(self):
options = self.Options()
exception_msg = ('%s file already exists in the current directory' %
options.config_filename)
gclient.os.path.exists(options.config_filename).AndReturn(True)
self.mox.ReplayAll()
self.assertRaisesError(exception_msg, gclient.CMDconfig, None, options,
(1,))
def testFromText(self):
options = self.Options(spec='config_source_content')
gclient.os.path.exists(options.config_filename).AndReturn(False)
gclient.GClient('.', options).AndReturn(gclient.GClient)
gclient.GClient.SetConfig(options.spec)
gclient.GClient.SaveConfig()
self.mox.ReplayAll()
gclient.CMDconfig(None, options, (1,),)
def testCreateClientFile(self):
options = self.Options()
gclient.os.path.exists(options.config_filename).AndReturn(False)
gclient.GClient('.', options).AndReturn(gclient.GClient)
gclient.GClient.SetDefaultConfig('the_name', 'http://svn/url/the_name',
'other')
gclient.GClient.SaveConfig()
self.mox.ReplayAll()
gclient.CMDconfig(None, options,
('http://svn/url/the_name', 'other', 'args', 'ignored'))
class GenericCommandTestCase(GclientTestCase):
def ReturnValue(self, command, return_value):
options = self.Options()
gclient.GClient.LoadCurrentConfig(options).AndReturn(gclient.GClient)
gclient.GClient.RunOnDeps(command, self.args).AndReturn(return_value)
self.mox.ReplayAll()
function = getattr(gclient, 'CMD' + command)
result = function(None, options, self.args)
self.assertEquals(result, return_value)
def BadClient(self, command):
options = self.Options()
gclient.GClient.LoadCurrentConfig(options).AndReturn(None)
self.mox.ReplayAll()
function = getattr(gclient, 'CMD' + command)
self.assertRaisesError(
"client not configured; see 'gclient config'",
function, None, options, self.args)
def Verbose(self, command):
options = self.Options(verbose=True)
gclient.GClient.LoadCurrentConfig(options).AndReturn(gclient.GClient)
text = "# Dummy content\nclient = 'my client'"
gclient.GClient.ConfigContent().AndReturn(text)
print(text)
gclient.GClient.RunOnDeps(command, self.args).AndReturn(0)
self.mox.ReplayAll()
function = getattr(gclient, 'CMD' + command)
result = function(None, options, self.args)
self.assertEquals(result, 0)
class TestCMDcleanup(GenericCommandTestCase):
def testGoodClient(self):
self.ReturnValue('cleanup', 0)
def testError(self):
self.ReturnValue('cleanup', 42)
def testBadClient(self):
self.BadClient('cleanup')
class TestCMDstatus(GenericCommandTestCase):
def testGoodClient(self):
self.ReturnValue('status', 0)
def testError(self):
self.ReturnValue('status', 42)
def testBadClient(self):
self.BadClient('status')
class TestCMDrunhooks(GenericCommandTestCase):
def Options(self, verbose=False, *args, **kwargs):
return self.OptionsObject(self, verbose=verbose, *args, **kwargs)
def testGoodClient(self):
self.ReturnValue('runhooks', 0)
def testError(self):
self.ReturnValue('runhooks', 42)
def testBadClient(self):
self.BadClient('runhooks')
class TestCMDupdate(GenericCommandTestCase):
def ReturnValue(self, command, return_value):
options = self.Options()
gclient.GClient.LoadCurrentConfig(options).AndReturn(gclient.GClient)
gclient.GClient.GetVar("solutions")
gclient.GClient.RunOnDeps(command, self.args).AndReturn(return_value)
self.mox.ReplayAll()
function = getattr(gclient, 'CMD' + command)
result = function(None, options, self.args)
self.assertEquals(result, return_value)
def Verbose(self, command):
options = self.Options(verbose=True)
gclient.GClient.LoadCurrentConfig(options).AndReturn(gclient.GClient)
gclient.GClient.GetVar("solutions")
text = "# Dummy content\nclient = 'my client'"
gclient.GClient.ConfigContent().AndReturn(text)
print(text)
gclient.GClient.RunOnDeps(command, self.args).AndReturn(0)
self.mox.ReplayAll()
function = getattr(gclient, 'CMD' + command)
result = function(None, options, self.args)
self.assertEquals(result, 0)
def Options(self, verbose=False, *args, **kwargs):
return self.OptionsObject(self, verbose=verbose, *args, **kwargs)
def testBasic(self):
self.ReturnValue('update', 0)
def testError(self):
self.ReturnValue('update', 42)
def testBadClient(self):
self.BadClient('update')
def testVerbose(self):
self.Verbose('update')
class TestCMDdiff(GenericCommandTestCase):
def Options(self, *args, **kwargs):
return self.OptionsObject(self, *args, **kwargs)
def testBasic(self):
self.ReturnValue('diff', 0)
def testError(self):
self.ReturnValue('diff', 42)
def testBadClient(self):
self.BadClient('diff')
def testVerbose(self):
self.Verbose('diff')
class TestCMDexport(GenericCommandTestCase):
def testBasic(self):
self.args = ['dir']
self.ReturnValue('export', 0)
def testError(self):
self.args = ['dir']
self.ReturnValue('export', 42)
def testBadClient(self):
self.args = ['dir']
self.BadClient('export')
class TestCMDpack(GenericCommandTestCase):
def Options(self, *args, **kwargs):
return self.OptionsObject(self, *args, **kwargs)
def testBasic(self):
self.ReturnValue('pack', 0)
def testError(self):
self.ReturnValue('pack', 42)
def testBadClient(self):
self.BadClient('pack')
class TestCMDrevert(GenericCommandTestCase):
def testBasic(self):
self.ReturnValue('revert', 0)
def testError(self):
self.ReturnValue('revert', 42)
def testBadClient(self):
self.BadClient('revert')
class GClientClassTestCase(GclientTestCase):
def testDir(self):
members = [
'ConfigContent', 'DEFAULT_CLIENT_FILE_TEXT',
'DEFAULT_SNAPSHOT_FILE_TEXT', 'DEFAULT_SNAPSHOT_SOLUTION_TEXT',
'DEPS_FILE', 'FileImpl', 'FromImpl', 'GetVar', 'LoadCurrentConfig',
'PrintRevInfo', 'RunOnDeps', 'SaveConfig', 'SetConfig',
'SetDefaultConfig',
'deps_os_choices', 'supported_commands',
]
# If you add a member, be sure to add the relevant test!
self.compareMembers(self._gclient_gclient('root_dir', 'options'), members)
def testSetConfig_ConfigContent_GetVar_SaveConfig_SetDefaultConfig(self):
options = self.Options()
text = "# Dummy content\nclient = 'my client'"
gclient.gclient_utils.FileWrite(
gclient.os.path.join(self.root_dir, options.config_filename),
text)
self.mox.ReplayAll()
client = self._gclient_gclient(self.root_dir, options)
client.SetConfig(text)
self.assertEqual(client.ConfigContent(), text)
self.assertEqual(client.GetVar('client'), 'my client')
self.assertEqual(client.GetVar('foo'), None)
client.SaveConfig()
solution_name = 'solution name'
solution_url = 'solution url'
safesync_url = 'safesync url'
default_text = gclient.GClient.DEFAULT_CLIENT_FILE_TEXT % {
'solution_name' : solution_name,
'solution_url' : solution_url,
'safesync_url' : safesync_url
}
client.SetDefaultConfig(solution_name, solution_url, safesync_url)
self.assertEqual(client.ConfigContent(), default_text)
solutions = [{
'name': solution_name,
'url': solution_url,
'custom_deps': {},
'safesync_url': safesync_url
}]
self.assertEqual(client.GetVar('solutions'), solutions)
self.assertEqual(client.GetVar('foo'), None)
def testLoadCurrentConfig(self):
options = self.Options()
gclient.os.path.realpath(self.root_dir).AndReturn(self.root_dir)
gclient.os.path.exists(
gclient.os.path.join(self.root_dir, options.config_filename)
).AndReturn(True)
gclient.GClient(self.root_dir, options).AndReturn(gclient.GClient)
gclient.GClient._LoadConfig()
self.mox.ReplayAll()
client = self._gclient_gclient.LoadCurrentConfig(options, self.root_dir)
def testRunOnDepsNoDeps(self):
solution_name = 'testRunOnDepsNoDeps_solution_name'
gclient_config = (
"solutions = [ {\n"
" 'name': '%s',\n"
" 'url': '%s',\n"
" 'custom_deps': {},\n"
"} ]\n"
) % (solution_name, self.url)
# pprint.pformat() is non-deterministic in this case!!
entries_content = (
"entries = \\\n"
"{ '%s': '%s'}\n"
) % (solution_name, self.url)
options = self.Options()
checkout_path = gclient.os.path.join(self.root_dir, solution_name)
gclient.os.path.exists(gclient.os.path.join(checkout_path, '.git')
).AndReturn(False)
# Expect a check for the entries file and we say there is not one.
gclient.os.path.exists(
gclient.os.path.join(self.root_dir, options.entries_filename)
).AndReturn(False)
# An scm will be requested for the solution.
scm_wrapper_sol = self.mox.CreateMockAnything()
gclient.gclient_scm.CreateSCM(self.url, self.root_dir, solution_name
).AndReturn(scm_wrapper_sol)
# Then an update will be performed.
scm_wrapper_sol.RunCommand('update', options, self.args, [])
# Then an attempt will be made to read its DEPS file.
gclient.gclient_utils.FileRead(
gclient.os.path.join(self.root_dir, solution_name,
gclient.GClient.DEPS_FILE)
).AndRaise(IOError(2, 'No DEPS file'))
# After everything is done, an attempt is made to write an entries
# file.
gclient.gclient_utils.FileWrite(
gclient.os.path.join(self.root_dir, options.entries_filename),
entries_content)
self.mox.ReplayAll()
client = self._gclient_gclient(self.root_dir, options)
client.SetConfig(gclient_config)
client.RunOnDeps('update', self.args)
def testRunOnDepsRelativePaths(self):
solution_name = 'testRunOnDepsRelativePaths_solution_name'
gclient_config = (
"solutions = [ {\n"
" 'name': '%s',\n"
" 'url': '%s',\n"
" 'custom_deps': {},\n"
"} ]\n"
) % (solution_name, self.url)
deps = (
"use_relative_paths = True\n"
"deps = {\n"
" 'src/t': 'svn://scm.t/trunk',\n"
"}\n")
entry_path = gclient.os.path.join(solution_name, 'src', 't'
).replace('\\', '\\\\')
entries_content = (
"entries = \\\n"
"{ '%s': '%s',\n"
" '%s': 'svn://scm.t/trunk'}\n"
) % (solution_name, self.url, entry_path)
scm_wrapper_sol = self.mox.CreateMockAnything()
scm_wrapper_t = self.mox.CreateMockAnything()
options = self.Options()
gclient.os.path.exists(
gclient.os.path.join(self.root_dir, solution_name, 'src', 't', '.git')
).AndReturn(False)
gclient.os.path.exists(
gclient.os.path.join(self.root_dir, solution_name, '.git')
).AndReturn(False)
# Expect a check for the entries file and we say there is not one.
gclient.os.path.exists(
gclient.os.path.join(self.root_dir, options.entries_filename)
).AndReturn(False)
# An scm will be requested for the solution.
gclient.gclient_scm.CreateSCM(self.url, self.root_dir, solution_name
).AndReturn(scm_wrapper_sol)
# Then an update will be performed.
scm_wrapper_sol.RunCommand('update', options, self.args, [])
# Then an attempt will be made to read its DEPS file.
gclient.gclient_utils.FileRead(
gclient.os.path.join(self.root_dir, solution_name,
gclient.GClient.DEPS_FILE)
).AndReturn(deps)
# Next we expect an scm to be request for dep src/t but it should
# use the url specified in deps and the relative path should now
# be relative to the DEPS file.
gclient.gclient_scm.CreateSCM(
'svn://scm.t/trunk',
self.root_dir,
gclient.os.path.join(solution_name, "src", "t")
).AndReturn(scm_wrapper_t)
scm_wrapper_t.RunCommand('update', options, self.args, [])
# After everything is done, an attempt is made to write an entries
# file.
gclient.gclient_utils.FileWrite(
gclient.os.path.join(self.root_dir, options.entries_filename),
entries_content)
self.mox.ReplayAll()
client = self._gclient_gclient(self.root_dir, options)
client.SetConfig(gclient_config)
client.RunOnDeps('update', self.args)
def testRunOnDepsCustomDeps(self):
solution_name = 'testRunOnDepsCustomDeps_solution_name'
gclient_config = (
"solutions = [ {\n"
" 'name': '%s',\n"
" 'url': '%s',\n"
" 'custom_deps': {\n"
" 'src/b': None,\n"
" 'src/n': 'svn://custom.n/trunk',\n"
" 'src/t': 'svn://custom.t/trunk',\n"
" }\n} ]\n"
) % (solution_name, self.url)
deps = (
"deps = {\n"
" 'src/b': 'svn://original.b/trunk',\n"
" 'src/t': 'svn://original.t/trunk',\n"
"}\n"
)
entries_content = (
"entries = \\\n"
"{ 'src/n': 'svn://custom.n/trunk',\n"
" 'src/t': 'svn://custom.t/trunk',\n"
" '%s': '%s'}\n"
) % (solution_name, self.url)
scm_wrapper_sol = self.mox.CreateMockAnything()
scm_wrapper_t = self.mox.CreateMockAnything()
scm_wrapper_n = self.mox.CreateMockAnything()
options = self.Options()
checkout_path = gclient.os.path.join(self.root_dir, solution_name)
gclient.os.path.exists(
gclient.os.path.join(checkout_path, '.git')).AndReturn(False)
gclient.os.path.exists(gclient.os.path.join(self.root_dir, 'src/n', '.git')
).AndReturn(False)
gclient.os.path.exists(gclient.os.path.join(self.root_dir, 'src/t', '.git')
).AndReturn(False)
# Expect a check for the entries file and we say there is not one.
gclient.os.path.exists(
gclient.os.path.join(self.root_dir, options.entries_filename)
).AndReturn(False)
# An scm will be requested for the solution.
gclient.gclient_scm.CreateSCM(self.url, self.root_dir, solution_name
).AndReturn(scm_wrapper_sol)
# Then an update will be performed.
scm_wrapper_sol.RunCommand('update', options, self.args, [])
# Then an attempt will be made to read its DEPS file.
gclient.gclient_utils.FileRead(
gclient.os.path.join(checkout_path, gclient.GClient.DEPS_FILE)
).AndReturn(deps)
# Next we expect an scm to be request for dep src/n even though it does not
# exist in the DEPS file.
gclient.gclient_scm.CreateSCM('svn://custom.n/trunk',
self.root_dir,
"src/n").AndReturn(scm_wrapper_n)
# Next we expect an scm to be request for dep src/t but it should
# use the url specified in custom_deps.
gclient.gclient_scm.CreateSCM('svn://custom.t/trunk',
self.root_dir,
"src/t").AndReturn(scm_wrapper_t)
scm_wrapper_n.RunCommand('update', options, self.args, [])
scm_wrapper_t.RunCommand('update', options, self.args, [])
# NOTE: the dep src/b should not create an scm at all.
# After everything is done, an attempt is made to write an entries
# file.
gclient.gclient_utils.FileWrite(
gclient.os.path.join(self.root_dir, options.entries_filename),
entries_content)
self.mox.ReplayAll()
client = self._gclient_gclient(self.root_dir, options)
client.SetConfig(gclient_config)
client.RunOnDeps('update', self.args)
# Regression test for Issue #11.
# http://code.google.com/p/gclient/issues/detail?id=11
def testRunOnDepsSharedDependency(self):
name_a = 'testRunOnDepsSharedDependency_a'
name_b = 'testRunOnDepsSharedDependency_b'
url_a = self.url + '/a'
url_b = self.url + '/b'
# config declares two solutions and each has a dependency to place
# http://svn.t/trunk at src/t.
gclient_config = (
"solutions = [ {\n"
" 'name': '%s',\n"
" 'url': '%s',\n"
" 'custom_deps': {},\n"
"}, {\n"
" 'name': '%s',\n"
" 'url': '%s',\n"
" 'custom_deps': {},\n"
"}\n]\n") % (name_a, url_a, name_b, url_b)
deps_b = deps_a = (
"deps = {\n"
" 'src/t' : 'http://svn.t/trunk',\n"
"}\n")
entries_content = (
"entries = \\\n"
"{ 'src/t': 'http://svn.t/trunk',\n"
" '%s': '%s',\n"
" '%s': '%s'}\n"
) % (name_a, url_a, name_b, url_b)
scm_wrapper_a = self.mox.CreateMockAnything()
scm_wrapper_b = self.mox.CreateMockAnything()
scm_wrapper_dep = self.mox.CreateMockAnything()
options = self.Options()
gclient.os.path.exists(gclient.os.path.join(self.root_dir, name_a, '.git')
).AndReturn(False)
gclient.os.path.exists(gclient.os.path.join(self.root_dir, name_b, '.git')
).AndReturn(False)
gclient.os.path.exists(gclient.os.path.join(self.root_dir, 'src/t', '.git')
).AndReturn(False)
# Expect a check for the entries file and we say there is not one.
gclient.os.path.exists(
gclient.os.path.join(self.root_dir, options.entries_filename)
).AndReturn(False)
# An scm will be requested for the first solution.
gclient.gclient_scm.CreateSCM(url_a, self.root_dir, name_a).AndReturn(
scm_wrapper_a)
# Then an attempt will be made to read it's DEPS file.
gclient.gclient_utils.FileRead(
gclient.os.path.join(self.root_dir, name_a, gclient.GClient.DEPS_FILE)
).AndReturn(deps_a)
# Then an update will be performed.
scm_wrapper_a.RunCommand('update', options, self.args, [])
# An scm will be requested for the second solution.
gclient.gclient_scm.CreateSCM(url_b, self.root_dir, name_b).AndReturn(
scm_wrapper_b)
# Then an attempt will be made to read its DEPS file.
gclient.gclient_utils.FileRead(
gclient.os.path.join(self.root_dir, name_b, gclient.GClient.DEPS_FILE)
).AndReturn(deps_b)
# Then an update will be performed.
scm_wrapper_b.RunCommand('update', options, self.args, [])
# Finally, an scm is requested for the shared dep.
gclient.gclient_scm.CreateSCM('http://svn.t/trunk', self.root_dir, 'src/t'
).AndReturn(scm_wrapper_dep)
# And an update is run on it.
scm_wrapper_dep.RunCommand('update', options, self.args, [])
# After everything is done, an attempt is made to write an entries file.
gclient.gclient_utils.FileWrite(
gclient.os.path.join(self.root_dir, options.entries_filename),
entries_content)
self.mox.ReplayAll()
client = self._gclient_gclient(self.root_dir, options)
client.SetConfig(gclient_config)
client.RunOnDeps('update', self.args)
def testRunOnDepsSuccess(self):
# Fake .gclient file.
name = 'testRunOnDepsSuccess_solution_name'
gclient_config = """solutions = [ {
'name': '%s',
'url': '%s',
'custom_deps': {},
}, ]""" % (name, self.url)
# pprint.pformat() is non-deterministic in this case!!
entries_content = (
"entries = \\\n"
"{ '%s': '%s'}\n"
) % (name, self.url)
options = self.Options()
gclient.os.path.exists(gclient.os.path.join(self.root_dir, name, '.git')
).AndReturn(False)
gclient.os.path.exists(
gclient.os.path.join(self.root_dir, options.entries_filename)
).AndReturn(False)
gclient.gclient_scm.CreateSCM(self.url, self.root_dir, name).AndReturn(
gclient.gclient_scm.CreateSCM)
gclient.gclient_scm.CreateSCM.RunCommand('update', options, self.args, [])
gclient.gclient_utils.FileRead(
gclient.os.path.join(self.root_dir, name, gclient.GClient.DEPS_FILE)
).AndReturn("Boo = 'a'")
gclient.gclient_utils.FileWrite(
gclient.os.path.join(self.root_dir, options.entries_filename),
entries_content)
self.mox.ReplayAll()
client = self._gclient_gclient(self.root_dir, options)
client.SetConfig(gclient_config)
client.RunOnDeps('update', self.args)
def testRunOnDepsRevisions(self):
def OptIsRev(options, rev):
if not options.revision == str(rev):
print("options.revision = %s" % options.revision)
return options.revision == str(rev)
def OptIsRevNone(options):
if options.revision:
print("options.revision = %s" % options.revision)
return options.revision == None
def OptIsRev42(options):
return OptIsRev(options, 42)
def OptIsRev123(options):
return OptIsRev(options, 123)
def OptIsRev333(options):
return OptIsRev(options, 333)
# Fake .gclient file.
gclient_config = """solutions = [ {
'name': 'src',
'url': '%s',
'custom_deps': {},
}, ]""" % self.url
# Fake DEPS file.
deps_content = """deps = {
'src/breakpad/bar': 'http://google-breakpad.googlecode.com/svn/trunk/src@285',
'foo/third_party/WebKit': '/trunk/deps/third_party/WebKit',
'src/third_party/cygwin': '/trunk/deps/third_party/cygwin@3248',
}
deps_os = {
'win': {
'src/foosad/asdf': 'svn://random_server:123/asd/python_24@5580',
},
'mac': {
'src/third_party/python_24': 'svn://random_server:123/trunk/python_24@5580',
},
}"""
cygwin_path = 'dummy path cygwin'
webkit_path = 'dummy path webkit'
entries_content = (
"entries = \\\n"
"{ 'foo/third_party/WebKit': '%s',\n"
" 'src': '%s',\n"
" 'src/breakpad/bar':"
" 'http://google-breakpad.googlecode.com/svn/trunk/src@285',\n"
" 'src/third_party/cygwin': '%s',\n"
" 'src/third_party/python_24':"
" 'svn://random_server:123/trunk/python_24@5580'}\n"
) % (webkit_path, self.url, cygwin_path)
scm_wrapper_bleh = self.mox.CreateMockAnything()
scm_wrapper_src = self.mox.CreateMockAnything()
scm_wrapper_src2 = self.mox.CreateMockAnything()
scm_wrapper_webkit = self.mox.CreateMockAnything()
scm_wrapper_breakpad = self.mox.CreateMockAnything()
scm_wrapper_cygwin = self.mox.CreateMockAnything()
scm_wrapper_python = self.mox.CreateMockAnything()
options = self.Options()
options.revisions = [ 'src@123', 'foo/third_party/WebKit@42',
'src/third_party/cygwin@333' ]
options.deps_os = 'mac'
# Also, pymox doesn't verify the order of function calling w.r.t. different
# mock objects. Pretty lame. So reorder as we wish to make it clearer.
gclient.gclient_utils.FileRead(
gclient.os.path.join(self.root_dir, 'src', gclient.GClient.DEPS_FILE)
).AndReturn(deps_content)
gclient.gclient_utils.FileWrite(
gclient.os.path.join(self.root_dir, options.entries_filename),
entries_content)
gclient.os.path.exists(gclient.os.path.join(self.root_dir, 'src', '.git')
).AndReturn(False)
gclient.os.path.exists(
gclient.os.path.join(self.root_dir, 'foo/third_party/WebKit', '.git')
).AndReturn(False)
gclient.os.path.exists(
gclient.os.path.join(self.root_dir, 'src/third_party/cygwin', '.git')
).AndReturn(False)
gclient.os.path.exists(
gclient.os.path.join(self.root_dir, 'src/third_party/python_24', '.git')
).AndReturn(False)
gclient.os.path.exists(
gclient.os.path.join(self.root_dir, 'src/breakpad/bar', '.git')
).AndReturn(False)
gclient.os.path.exists(
gclient.os.path.join(self.root_dir, options.entries_filename)
).AndReturn(False)
gclient.gclient_scm.CreateSCM(self.url, self.root_dir, 'src').AndReturn(
scm_wrapper_src)
scm_wrapper_src.RunCommand('update', mox.Func(OptIsRev123), self.args, [])
gclient.gclient_scm.CreateSCM(self.url, self.root_dir,
None).AndReturn(scm_wrapper_src2)
scm_wrapper_src2.FullUrlForRelativeUrl('/trunk/deps/third_party/cygwin@3248'
).AndReturn(cygwin_path)
gclient.gclient_scm.CreateSCM(self.url, self.root_dir,
None).AndReturn(scm_wrapper_src2)
scm_wrapper_src2.FullUrlForRelativeUrl('/trunk/deps/third_party/WebKit'
).AndReturn(webkit_path)
gclient.gclient_scm.CreateSCM(
webkit_path, self.root_dir, 'foo/third_party/WebKit'
).AndReturn(scm_wrapper_webkit)
scm_wrapper_webkit.RunCommand('update', mox.Func(OptIsRev42), self.args, [])
gclient.gclient_scm.CreateSCM(
'http://google-breakpad.googlecode.com/svn/trunk/src@285',
self.root_dir, 'src/breakpad/bar').AndReturn(scm_wrapper_breakpad)
scm_wrapper_breakpad.RunCommand('update', mox.Func(OptIsRevNone),
self.args, [])
gclient.gclient_scm.CreateSCM(
cygwin_path, self.root_dir, 'src/third_party/cygwin'
).AndReturn(scm_wrapper_cygwin)
scm_wrapper_cygwin.RunCommand('update', mox.Func(OptIsRev333), self.args,
[])
gclient.gclient_scm.CreateSCM(
'svn://random_server:123/trunk/python_24@5580',
self.root_dir,
'src/third_party/python_24'
).AndReturn(scm_wrapper_python)
scm_wrapper_python.RunCommand('update', mox.Func(OptIsRevNone), self.args,
[])
self.mox.ReplayAll()
client = self._gclient_gclient(self.root_dir, options)
client.SetConfig(gclient_config)
client.RunOnDeps('update', self.args)
def testRunOnDepsConflictingRevisions(self):
# Fake .gclient file.
name = 'testRunOnDepsConflictingRevisions_solution_name'
gclient_config = """solutions = [ {
'name': '%s',
'url': '%s',
'custom_deps': {},
'custom_vars': {},
}, ]""" % (name, self.url)
# Fake DEPS file.
deps_content = """deps = {
'foo/third_party/WebKit': '/trunk/deps/third_party/WebKit',
}"""
options = self.Options()
options.revisions = [ 'foo/third_party/WebKit@42',
'foo/third_party/WebKit@43' ]
client = self._gclient_gclient(self.root_dir, options)
client.SetConfig(gclient_config)
exception = "Conflicting revision numbers specified."
try:
client.RunOnDeps('update', self.args)
except gclient.gclient_utils.Error, e:
self.assertEquals(e.args[0], exception)
else:
self.fail('%s not raised' % exception)
def testRunOnDepsSuccessVars(self):
# Fake .gclient file.
name = 'testRunOnDepsSuccessVars_solution_name'
gclient_config = """solutions = [ {
'name': '%s',
'url': '%s',
'custom_deps': {},
'custom_vars': {},
}, ]""" % (name, self.url)
# Fake DEPS file.
deps_content = """vars = {
'webkit': '/trunk/bar/',
}
deps = {
'foo/third_party/WebKit': Var('webkit') + 'WebKit',
}"""
webkit_path = 'dummy path webkit'
entries_content = (
"entries = \\\n"
"{ 'foo/third_party/WebKit': '%s',\n"
" '%s': '%s'}\n"
) % (webkit_path, name, self.url)
scm_wrapper_webkit = self.mox.CreateMockAnything()
scm_wrapper_src = self.mox.CreateMockAnything()
options = self.Options()
gclient.gclient_utils.FileRead(
gclient.os.path.join(self.root_dir, name,
gclient.GClient.DEPS_FILE)
).AndReturn(deps_content)
gclient.gclient_utils.FileWrite(
gclient.os.path.join(self.root_dir, options.entries_filename),
entries_content)
gclient.os.path.exists(
gclient.os.path.join(self.root_dir, 'foo/third_party/WebKit', '.git')
).AndReturn(False)
gclient.os.path.exists(
gclient.os.path.join(self.root_dir, name, '.git')
).AndReturn(False)
gclient.os.path.exists(
gclient.os.path.join(self.root_dir, options.entries_filename)
).AndReturn(False)
gclient.gclient_scm.CreateSCM(self.url, self.root_dir, name).AndReturn(
gclient.gclient_scm.CreateSCM)
gclient.gclient_scm.CreateSCM.RunCommand('update', options, self.args, [])
gclient.gclient_scm.CreateSCM(self.url, self.root_dir, None
).AndReturn(scm_wrapper_src)
scm_wrapper_src.FullUrlForRelativeUrl('/trunk/bar/WebKit'
).AndReturn(webkit_path)
gclient.gclient_scm.CreateSCM(
webkit_path, self.root_dir, 'foo/third_party/WebKit'
).AndReturn(gclient.gclient_scm.CreateSCM)
gclient.gclient_scm.CreateSCM.RunCommand('update', options, self.args, [])
self.mox.ReplayAll()
client = self._gclient_gclient(self.root_dir, options)
client.SetConfig(gclient_config)
client.RunOnDeps('update', self.args)
def testRunOnDepsSuccessCustomVars(self):
# Fake .gclient file.
name = 'testRunOnDepsSuccessCustomVars_solution_name'
gclient_config = """solutions = [ {
'name': '%s',
'url': '%s',
'custom_deps': {},
'custom_vars': {'webkit': '/trunk/bar_custom/'},
}, ]""" % (name, self.url)
# Fake DEPS file.
deps_content = """vars = {
'webkit': '/trunk/bar/',
}
deps = {
'foo/third_party/WebKit': Var('webkit') + 'WebKit',
}"""
webkit_path = 'dummy path webkit'
entries_content = (
"entries = \\\n"
"{ 'foo/third_party/WebKit': '%s',\n"
" '%s': '%s'}\n"
) % (webkit_path, name, self.url)
scm_wrapper_webkit = self.mox.CreateMockAnything()
scm_wrapper_src = self.mox.CreateMockAnything()
options = self.Options()
gclient.gclient_utils.FileRead(
gclient.os.path.join(self.root_dir, name, gclient.GClient.DEPS_FILE)
).AndReturn(deps_content)
gclient.gclient_utils.FileWrite(
gclient.os.path.join(self.root_dir, options.entries_filename),
entries_content)
gclient.os.path.exists(
gclient.os.path.join(self.root_dir, 'foo/third_party/WebKit', '.git')
).AndReturn(False)
gclient.os.path.exists(
gclient.os.path.join(self.root_dir, name, '.git')
).AndReturn(False)
gclient.os.path.exists(
gclient.os.path.join(self.root_dir, options.entries_filename)
).AndReturn(False)
gclient.gclient_scm.CreateSCM(self.url, self.root_dir, name).AndReturn(
gclient.gclient_scm.CreateSCM)
gclient.gclient_scm.CreateSCM.RunCommand('update', options, self.args, [])
gclient.gclient_scm.CreateSCM(self.url, self.root_dir,
None).AndReturn(scm_wrapper_src)
scm_wrapper_src.FullUrlForRelativeUrl('/trunk/bar_custom/WebKit'
).AndReturn(webkit_path)
gclient.gclient_scm.CreateSCM(webkit_path, self.root_dir,
'foo/third_party/WebKit').AndReturn(gclient.gclient_scm.CreateSCM)
gclient.gclient_scm.CreateSCM.RunCommand('update', options, self.args, [])
self.mox.ReplayAll()
client = self._gclient_gclient(self.root_dir, options)
client.SetConfig(gclient_config)
client.RunOnDeps('update', self.args)
def testRunOnDepsFailureVars(self):
# Fake .gclient file.
name = 'testRunOnDepsFailureVars_solution_name'
gclient_config = """solutions = [ {
'name': '%s',
'url': '%s',
'custom_deps': {},
'custom_vars': {},
}, ]""" % (name, self.url)
# Fake DEPS file.
deps_content = """deps = {
'foo/third_party/WebKit': Var('webkit') + 'WebKit',
}"""
options = self.Options()
gclient.gclient_utils.FileRead(
gclient.os.path.join(self.root_dir, name, gclient.GClient.DEPS_FILE)
).AndReturn(deps_content)
gclient.gclient_scm.CreateSCM(self.url, self.root_dir, name).AndReturn(
gclient.gclient_scm.CreateSCM)
gclient.gclient_scm.CreateSCM.RunCommand('update', options, self.args, [])
self.mox.ReplayAll()
client = self._gclient_gclient(self.root_dir, options)
client.SetConfig(gclient_config)
exception = "Var is not defined: webkit"
try:
client.RunOnDeps('update', self.args)
except gclient.gclient_utils.Error, e:
self.assertEquals(e.args[0], exception)
else:
self.fail('%s not raised' % exception)
def testRunOnDepsFailureInvalidCommand(self):
options = self.Options()
self.mox.ReplayAll()
client = self._gclient_gclient(self.root_dir, options)
exception = "'foo' is an unsupported command"
self.assertRaisesError(exception, self._gclient_gclient.RunOnDeps, client,
'foo', self.args)
def testRunOnDepsFailureEmpty(self):
options = self.Options()
self.mox.ReplayAll()
client = self._gclient_gclient(self.root_dir, options)
exception = "No solution specified"
self.assertRaisesError(exception, self._gclient_gclient.RunOnDeps, client,
'update', self.args)
def testFromImplOne(self):
base_url = 'svn://base@123'
deps_content = (
"deps = {\n"
" 'base': '%s',\n"
" 'main': From('base'),\n"
"}\n" % base_url
)
main_url = 'svn://main@456'
base_deps_content = (
"deps = {\n"
" 'main': '%s',\n"
"}\n" % main_url
)
# Fake .gclient file.
name = 'testFromImplOne_solution_name'
gclient_config = (
"solutions = [ {\n"
"'name': '%s',\n"
"'url': '%s',\n"
"'custom_deps': {},\n"
"}, ]" % (name, self.url))
options = self.Options()
gclient.os.path.exists(gclient.os.path.join(self.root_dir, 'main', '.git')
).AndReturn(False)
gclient.os.path.exists(gclient.os.path.join(self.root_dir, 'base', '.git')
).AndReturn(False)
gclient.os.path.exists(gclient.os.path.join(self.root_dir, name, '.git')
).AndReturn(False)
gclient.gclient_scm.CreateSCM(self.url, self.root_dir, name).AndReturn(
gclient.gclient_scm.CreateSCM)
gclient.gclient_scm.CreateSCM.RunCommand('update', options, self.args, [])
gclient.gclient_utils.FileRead(
gclient.os.path.join(self.root_dir, name, gclient.GClient.DEPS_FILE)
).AndReturn(deps_content)
# base gets updated.
gclient.gclient_scm.CreateSCM(base_url, self.root_dir, 'base').AndReturn(
gclient.gclient_scm.CreateSCM)
gclient.gclient_scm.CreateSCM.RunCommand('update', options, self.args, [])
gclient.gclient_utils.FileRead(
gclient.os.path.join(self.root_dir, 'base', gclient.GClient.DEPS_FILE)
).AndReturn(base_deps_content)
# main gets updated.
gclient.gclient_scm.CreateSCM(main_url, self.root_dir, 'main').AndReturn(
gclient.gclient_scm.CreateSCM)
gclient.gclient_scm.CreateSCM.RunCommand('update', options, self.args, [])
# Process is done and will write an .gclient_entries.
gclient.os.path.exists(
gclient.os.path.join(self.root_dir, options.entries_filename)
).AndReturn(False)
gclient.gclient_utils.FileWrite(
gclient.os.path.join(self.root_dir, options.entries_filename),
mox.IgnoreArg())
self.mox.ReplayAll()
client = self._gclient_gclient(self.root_dir, options)
client.SetConfig(gclient_config)
client.RunOnDeps('update', self.args)
def testFromImplTwo(self):
base_url = 'svn://base@123'
deps_content = (
"deps = {\n"
" 'base': '%s',\n"
" 'main': From('base', 'src/main'),\n"
"}\n" % base_url
)
main_url = 'svn://main@456'
base_deps_content = (
"deps = {\n"
" 'src/main': '%s',\n"
"}\n" % main_url
)
# Fake .gclient file.
name = 'testFromImplTwo_solution_name'
gclient_config = (
"solutions = [ {\n"
"'name': '%s',\n"
"'url': '%s',\n"
"'custom_deps': {},\n"
"}, ]" % (name, self.url))
options = self.Options()
gclient.os.path.exists(gclient.os.path.join(self.root_dir, 'main', '.git')
).AndReturn(False)
gclient.os.path.exists(gclient.os.path.join(self.root_dir, 'base', '.git')
).AndReturn(False)
gclient.os.path.exists(gclient.os.path.join(self.root_dir, name, '.git')
).AndReturn(False)
gclient.gclient_scm.CreateSCM(self.url, self.root_dir, name).AndReturn(
gclient.gclient_scm.CreateSCM)
gclient.gclient_scm.CreateSCM.RunCommand('update', options, self.args, [])
gclient.gclient_utils.FileRead(
gclient.os.path.join(self.root_dir, name, gclient.GClient.DEPS_FILE)
).AndReturn(deps_content)
# base gets updated.
gclient.gclient_scm.CreateSCM(base_url, self.root_dir, 'base').AndReturn(
gclient.gclient_scm.CreateSCM)
gclient.gclient_scm.CreateSCM.RunCommand('update', options, self.args, [])
gclient.gclient_utils.FileRead(
gclient.os.path.join(self.root_dir, 'base', gclient.GClient.DEPS_FILE)
).AndReturn(base_deps_content)
# main gets updated.
gclient.gclient_scm.CreateSCM(main_url, self.root_dir, 'main').AndReturn(
gclient.gclient_scm.CreateSCM)
gclient.gclient_scm.CreateSCM.RunCommand('update', options, self.args, [])
# Process is done and will write an .gclient_entries.
gclient.os.path.exists(
gclient.os.path.join(self.root_dir, options.entries_filename)
).AndReturn(False)
gclient.gclient_utils.FileWrite(
gclient.os.path.join(self.root_dir, options.entries_filename),
mox.IgnoreArg())
self.mox.ReplayAll()
client = self._gclient_gclient(self.root_dir, options)
client.SetConfig(gclient_config)
client.RunOnDeps('update', self.args)
def testFromImplTwoRelatvie(self):
base_url = 'svn://base@123'
deps_content = (
"deps = {\n"
" 'base': '%s',\n"
" 'main': From('base', 'src/main'),\n"
"}\n" % base_url
)
main_url = '/relative@456'
base_deps_content = (
"deps = {\n"
" 'src/main': '%s',\n"
"}\n" % main_url
)
# Fake .gclient file.
name = 'testFromImplTwo_solution_name'
gclient_config = (
"solutions = [ {\n"
"'name': '%s',\n"
"'url': '%s',\n"
"'custom_deps': {},\n"
"}, ]" % (name, self.url))
options = self.Options()
gclient.os.path.exists(gclient.os.path.join(self.root_dir, 'main', '.git')
).AndReturn(False)
gclient.os.path.exists(gclient.os.path.join(self.root_dir, 'base', '.git')
).AndReturn(False)
gclient.os.path.exists(gclient.os.path.join(self.root_dir, name, '.git')
).AndReturn(False)
gclient.gclient_scm.CreateSCM(self.url, self.root_dir, name).AndReturn(
gclient.gclient_scm.CreateSCM)
gclient.gclient_scm.CreateSCM.RunCommand('update', options, self.args, [])
gclient.gclient_utils.FileRead(
gclient.os.path.join(self.root_dir, name, gclient.GClient.DEPS_FILE)
).AndReturn(deps_content)
# base gets updated.
gclient.gclient_scm.CreateSCM(base_url, self.root_dir, 'base').AndReturn(
gclient.gclient_scm.CreateSCM)
gclient.gclient_scm.CreateSCM.RunCommand('update', options, self.args, [])
gclient.gclient_utils.FileRead(
gclient.os.path.join(self.root_dir, 'base', gclient.GClient.DEPS_FILE)
).AndReturn(base_deps_content)
# main gets updated after resolving the relative url.
gclient.gclient_scm.CreateSCM(base_url, self.root_dir, None).AndReturn(
gclient.gclient_scm.CreateSCM)
gclient.gclient_scm.CreateSCM.FullUrlForRelativeUrl(main_url
).AndReturn('svn://base' + main_url)
gclient.gclient_scm.CreateSCM('svn://base' + main_url, self.root_dir,
'main').AndReturn(gclient.gclient_scm.CreateSCM)
gclient.gclient_scm.CreateSCM.RunCommand('update', options, self.args, [])
# Process is done and will write an .gclient_entries.
gclient.os.path.exists(
gclient.os.path.join(self.root_dir, options.entries_filename)
).AndReturn(False)
gclient.gclient_utils.FileWrite(
gclient.os.path.join(self.root_dir, options.entries_filename),
mox.IgnoreArg())
self.mox.ReplayAll()
client = self._gclient_gclient(self.root_dir, options)
client.SetConfig(gclient_config)
client.RunOnDeps('update', self.args)
def testFileImpl(self):
# Fake .gclient file.
name = "testFileImpl"
gclient_config = (
"solutions = [ { 'name': '%s',"
"'url': '%s', } ]" % (name, self.url)
)
# Fake DEPS file.
target = "chromium_deps"
deps_content = (
"deps = {"
" '%s': File('%s/DEPS') }" % (target, self.url)
)
gclient.gclient_scm.CreateSCM(self.url, self.root_dir, name).AndReturn(
gclient.gclient_scm.CreateSCM)
options = self.Options()
gclient.gclient_scm.CreateSCM.RunCommand('update', options, self.args, [])
gclient.gclient_utils.FileRead(
gclient.os.path.join(self.root_dir, name, gclient.GClient.DEPS_FILE)
).AndReturn(deps_content)
gclient.os.path.exists(
gclient.os.path.join(self.root_dir, name, '.git')
).AndReturn(False)
gclient.os.path.exists(
gclient.os.path.join(self.root_dir, options.entries_filename)
).AndReturn(False)
# This is where gclient tries to do the initial checkout.
gclient.gclient_scm.CreateSCM(self.url, self.root_dir, target).AndReturn(
gclient.gclient_scm.CreateSCM)
gclient.gclient_scm.CreateSCM.RunCommand('updatesingle', options,
self.args + ["DEPS"], [])
gclient.gclient_utils.FileWrite(
gclient.os.path.join(self.root_dir, options.entries_filename),
"entries = \\\n{ '%s': '%s'}\n" % (name, self.url))
self.mox.ReplayAll()
client = self._gclient_gclient(self.root_dir, options)
client.SetConfig(gclient_config)
client.RunOnDeps('update', self.args)
def test_PrintRevInfo(self):
# TODO(aharper): no test yet for revinfo, lock it down once we've verified
# implementation for Pulse plugin
pass
# No test for internal functions.
def test_GetAllDeps(self):
pass
def test_GetDefaultSolutionDeps(self):
pass
def test_LoadConfig(self):
pass
def test_ReadEntries(self):
pass
def test_SaveEntries(self):
pass
def test_VarImpl(self):
pass
if __name__ == '__main__':
import unittest
unittest.main()
# vim: ts=2:sw=2:tw=80:et:
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