Commit 8f041185 authored by maruel@chromium.org's avatar maruel@chromium.org

Revert "Reapply 48271 with fix."

Still broken.

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

git-svn-id: svn://svn.chromium.org/chrome/trunk/tools/depot_tools@48290 0039d316-1c4b-4281-b951-d872f2087c98
parent 3365c913
......@@ -10,6 +10,7 @@ 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.4"
__version__ = "0.3.7"
import errno
import logging
......@@ -73,6 +73,22 @@ 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."""
......@@ -454,8 +470,6 @@ solutions = [
def _RunHookAction(self, hook_dict, matching_file_list):
"""Runs the action from a single hook.
"""
logging.info(hook_dict)
logging.info(matching_file_list)
command = hook_dict['action'][:]
if command[0] == 'python':
# If the hook specified "python" as the first item, the action is a
......@@ -799,15 +813,19 @@ 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.
def CMDcleanup(parser, args):
"""Cleans up all working copies.
Additional options and args may be passed to 'svn cleanup'.
Mostly svn-specific. Simply runs 'svn cleanup' for each module.
usage: cleanup [options] [--] [svn cleanup args/options]
Valid options:
--verbose : output additional diagnostics
"""
(options, args) = parser.parse_args(args)
client = GClient.LoadCurrentConfig(options)
if not client:
raise gclient_utils.Error("client not configured; see 'gclient config'")
......@@ -818,23 +836,32 @@ Mostly svn-specific. Simply runs 'svn cleanup' for each module.
return client.RunOnDeps('cleanup', args)
@attr('usage', '[url] [safesync url]')
def CMDconfig(parser, args):
def CMDconfig(parser, options, 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.
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":{}}]'
"""
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'")
......@@ -859,9 +886,8 @@ URL.
return 0
def CMDexport(parser, args):
def CMDexport(parser, options, 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)
......@@ -876,19 +902,30 @@ def CMDexport(parser, args):
return client.RunOnDeps('export', args)
@attr('epilog', """Example:
gclient pack > patch.txt
generate simple patch for configured client and dependences
""")
def CMDpack(parser, args):
def CMDpack(parser, options, args):
"""Generate a patch which can be applied at the root of the tree.
Internally, runs 'svn diff'/'git diff' on each checked out module and
Internally, runs 'svn 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'.
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
"""
(options, args) = parser.parse_args(args)
client = GClient.LoadCurrentConfig(options)
if not client:
raise gclient_utils.Error("client not configured; see 'gclient config'")
......@@ -899,9 +936,17 @@ checked out tree via 'patch -p0 < patchfile'.
return client.RunOnDeps('pack', args)
def CMDstatus(parser, args):
"""Show modification status for every dependencies."""
(options, args) = parser.parse_args(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
"""
client = GClient.LoadCurrentConfig(options)
if not client:
raise gclient_utils.Error("client not configured; see 'gclient config'")
......@@ -912,7 +957,31 @@ def CMDstatus(parser, args):
return client.RunOnDeps('status', args)
@attr('epilog', """Examples:
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:
gclient sync
update files from SCM according to current configuration,
*for modules which have changed since last update or sync*
......@@ -921,33 +990,7 @@ def CMDstatus(parser, args):
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:
......@@ -980,13 +1023,31 @@ def CMDsync(parser, args):
return client.RunOnDeps('update', args)
def CMDupdate(parser, args):
def CMDupdate(parser, options, args):
"""Alias for the sync command. Deprecated."""
return CMDsync(parser, args)
return CMDsync(parser, options, args)
def CMDdiff(parser, options, args):
"""Display the differences between two revisions of modules.
def CMDdiff(parser, args):
"""Displays local diff for every dependencies."""
(options, args) = parser.parse_args(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
"""
client = GClient.LoadCurrentConfig(options)
if not client:
raise gclient_utils.Error("client not configured; see 'gclient config'")
......@@ -997,24 +1058,24 @@ def CMDdiff(parser, args):
return client.RunOnDeps('diff', args)
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
def CMDrevert(parser, options, args):
"""Revert every file in every managed directory in the client view."""
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, 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)
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
"""
client = GClient.LoadCurrentConfig(options)
if not client:
raise gclient_utils.Error("client not configured; see 'gclient config'")
......@@ -1023,16 +1084,18 @@ def CMDrunhooks(parser, args):
# client dict, but more legible, and it might contain helpful comments.
print(client.ConfigContent())
options.force = True
options.nohooks = False
return client.RunOnDeps('runhooks', 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)
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'
client = GClient.LoadCurrentConfig(options)
if not client:
raise gclient_utils.Error("client not configured; see 'gclient config'")
......@@ -1040,45 +1103,70 @@ def CMDrevinfo(parser, args):
return 0
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)
def CMDhelp(parser, options, args):
"""Prints general help or command-specific documentation."""
if len(args) == 1:
return Main(args + ['--help'])
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')]))
parser.print_help()
return 0
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 Command(command):
return getattr(sys.modules[__name__], 'CMD' + command, CMDhelp)
def Main(argv):
"""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 = optparse.OptionParser(usage=DEFAULT_USAGE_TEXT,
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):
......@@ -1088,22 +1176,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 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 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 "__main__" == __name__:
......
......@@ -205,19 +205,14 @@ class FakeRepos(object):
# - versioned and unversioned reference
# - relative and full reference
# - deps_os
# TODO(maruel):
# - var
# - hooks
# TODO(maruel):
# - File
# - $matching_files
# - use_relative_paths
self._commit_svn(file_system(1, """
vars = {
'DummyVariable': 'third_party',
}
deps = {
'src/other': 'svn://%(host)s/svn/trunk/other',
'src/third_party/fpp': '/trunk/' + Var('DummyVariable') + '/foo',
'src/third_party/fpp': '/trunk/third_party/foo',
}
deps_os = {
'mac': {
......@@ -230,21 +225,6 @@ deps = {
'src/other': 'svn://%(host)s/svn/trunk/other',
'src/third_party/foo': '/trunk/third_party/foo@1',
}
# I think this is wrong to have the hooks run from the base of the gclient
# checkout. It's maybe a bit too late to change that behavior.
hooks = [
{
'pattern': '.',
'action': ['python', '-c',
'open(\\'src/hooked1\\', \\'w\\').write(\\'hooked1\\')'],
},
{
# Should not be run.
'pattern': 'nonexistent',
'action': ['python', '-c',
'open(\\'src/hooked2\\', \\'w\\').write(\\'hooked2\\')'],
},
]
""" % { 'host': '127.0.0.1' }))
def setUpGIT(self):
......@@ -261,20 +241,15 @@ hooks = [
# - versioned and unversioned reference
# - relative and full reference
# - deps_os
# TODO(maruel):
# - var
# - hooks
# TODO(maruel):
# - File
# - $matching_files
# - use_relative_paths
self._commit_git('repo_1', {
'DEPS': """
vars = {
'DummyVariable': 'repo',
}
deps = {
'src/repo2': 'git://%(host)s/git/repo_2',
'src/repo2/repo3': '/' + Var('DummyVariable') + '_3',
'src/repo2/repo3': '/repo_3',
}
deps_os = {
'mac': {
......@@ -314,21 +289,6 @@ deps = {
'src/repo2': 'git://%(host)s/git/repo_2@%(hash)s',
'src/repo2/repo_renamed': '/repo_3',
}
# I think this is wrong to have the hooks run from the base of the gclient
# checkout. It's maybe a bit too late to change that behavior.
hooks = [
{
'pattern': '.',
'action': ['python', '-c',
'open(\\'src/hooked1\\', \\'w\\').write(\\'hooked1\\')'],
},
{
# Should not be run.
'pattern': 'nonexistent',
'action': ['python', '-c',
'open(\\'src/hooked2\\', \\'w\\').write(\\'hooked2\\')'],
},
]
""" % { 'host': '127.0.0.1', 'hash': self.git_hashes['repo_2'][0][0] },
'origin': "git/repo_1@2\n"
})
......
......@@ -13,7 +13,6 @@ This test assumes GClientSmokeBase.URL_BASE is valid.
import logging
import os
import pprint
import re
import shutil
import subprocess
import sys
......@@ -107,20 +106,15 @@ class GClientSmokeBase(unittest.TestCase):
(stdout, stderr) = process.communicate()
return (stdout, stderr, process.returncode)
def checkString(self, expected, result):
if expected != result:
# Strip the begining
while expected and result and expected[0] == result[0]:
expected = expected[1:]
result = result[1:]
# The exception trace makes it hard to read so dump it too.
if '\n' in result:
print result
self.assertEquals(expected, result)
def check(self, expected, results):
self.checkString(expected[0], results[0])
self.checkString(expected[1], results[1])
def checkString(expected, result):
if expected != result:
while expected and result and expected[0] == result[0]:
expected = expected[1:]
result = result[1:]
self.assertEquals(expected, result)
checkString(expected[0], results[0])
checkString(expected[1], results[1])
self.assertEquals(expected[2], results[2])
def assertTree(self, tree):
......@@ -137,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(1197, len(result[0]))
self.assertEquals(3189, len(result[0]))
self.assertEquals(0, len(result[1]))
self.assertEquals(0, result[2])
......@@ -158,13 +152,12 @@ class GClientSmoke(GClientSmokeBase):
class GClientSmokeSVN(GClientSmokeBase):
"""sync is the most important command. Hence test it more."""
def testSync(self):
"""Test pure gclient svn checkout, example of Chromium checkout"""
self.gclient(['config', self.svn_base + 'trunk/src/'])
# Test unversioned checkout.
results = self.gclient(['sync', '--deps', 'mac'])
logging.debug(results[0])
out = results[0].splitlines(False)
self.assertEquals(17, len(out))
self.checkString('', results[1])
self.assertEquals('', results[1])
self.assertEquals(0, results[2])
tree = mangle_svn_tree(
(join('trunk', 'src'), 'src', FAKE.svn_revs[-1]),
......@@ -172,19 +165,13 @@ class GClientSmokeSVN(GClientSmokeBase):
FAKE.svn_revs[1]),
(join('trunk', 'other'), join('src', 'other'), FAKE.svn_revs[2]),
)
tree[join('src', 'hooked1')] = 'hooked1'
self.assertTree(tree)
# Manually remove hooked1 before synching to make sure it's not recreated.
os.remove(join(self.root_dir, 'src', 'hooked1'))
# Test incremental versioned sync: sync backward.
results = self.gclient(['sync', '--revision', 'src@1', '--deps', 'mac',
'--delete_unversioned_trees'])
logging.debug(results[0])
out = results[0].splitlines(False)
self.assertEquals(19, len(out))
self.checkString('', results[1])
self.assertEquals('', results[1])
self.assertEquals(0, results[2])
tree = mangle_svn_tree(
(join('trunk', 'src'), 'src', FAKE.svn_revs[1]),
......@@ -199,9 +186,7 @@ class GClientSmokeSVN(GClientSmokeBase):
# Test incremental sync: delete-unversioned_trees isn't there.
results = self.gclient(['sync', '--deps', 'mac'])
logging.debug(results[0])
out = results[0].splitlines(False)
self.assertEquals(21, len(out))
self.checkString('', results[1])
self.assertEquals('', results[1])
self.assertEquals(0, results[2])
tree = mangle_svn_tree(
(join('trunk', 'src'), 'src', FAKE.svn_revs[-1]),
......@@ -214,35 +199,28 @@ class GClientSmokeSVN(GClientSmokeBase):
join('src', 'third_party', 'prout'),
FAKE.svn_revs[2]),
)
tree[join('src', 'hooked1')] = 'hooked1'
self.assertTree(tree)
def testRevertAndStatus(self):
self.gclient(['config', self.svn_base + 'trunk/src/'])
# Tested in testSync.
self.gclient(['sync', '--deps', 'mac'])
results = self.gclient(['sync', '--deps', 'mac'])
write(join(self.root_dir, 'src', 'third_party', 'foo', 'hi'), 'Hey!')
results = self.gclient(['status'])
out = results[0].splitlines(False)
self.assertEquals(7, len(out))
self.assertEquals(out[0], '')
self.assertTrue(out[1].startswith('________ running \'svn status\' in \''))
self.assertEquals(out[2], '? other')
self.assertEquals(out[3], '? hooked1')
self.assertEquals(out[4], '? third_party/foo')
self.assertEquals(out[5], '')
self.assertTrue(out[6].startswith('________ running \'svn status\' in \''))
self.assertEquals(out[7], '? hi')
self.assertEquals(8, len(out))
self.assertEquals(out[3], '? third_party/foo')
self.assertEquals(out[4], '')
self.assertTrue(out[5].startswith('________ running \'svn status\' in \''))
self.assertEquals(out[6], '? hi')
self.assertEquals('', results[1])
self.assertEquals(0, results[2])
# Revert implies --force implies running hooks without looking at pattern
# matching.
results = self.gclient(['revert'])
out = results[0].splitlines(False)
self.assertEquals(22, len(out))
self.checkString('', results[1])
self.assertEquals('', results[1])
self.assertEquals(0, results[2])
tree = mangle_svn_tree(
(join('trunk', 'src'), 'src', FAKE.svn_revs[-1]),
......@@ -250,50 +228,26 @@ class GClientSmokeSVN(GClientSmokeBase):
FAKE.svn_revs[1]),
(join('trunk', 'other'), join('src', 'other'), FAKE.svn_revs[2]),
)
tree[join('src', 'hooked1')] = 'hooked1'
tree[join('src', 'hooked2')] = 'hooked2'
self.assertTree(tree)
results = self.gclient(['status'])
out = results[0].splitlines(False)
self.assertEquals(4, len(out))
self.assertEquals(out[0], '')
self.assertTrue(out[1].startswith('________ running \'svn status\' in \''))
self.assertEquals(out[2], '? other')
self.assertEquals(out[3], '? hooked1')
self.assertEquals(out[4], '? hooked2')
self.assertEquals(out[5], '? third_party/foo')
self.assertEquals(6, len(out))
self.checkString('', results[1])
self.assertEquals(0, results[2])
def testRunHooks(self):
self.gclient(['config', self.svn_base + 'trunk/src/'])
self.gclient(['sync', '--deps', 'mac'])
results = self.gclient(['runhooks'])
out = results[0].splitlines(False)
self.assertEquals(4, len(out))
self.assertEquals(out[0], '')
self.assertTrue(re.match(r'^________ running \'.*?python -c '
r'open\(\'src/hooked1\', \'w\'\)\.write\(\'hooked1\'\)\' in \'.*',
out[1]))
self.assertEquals(out[2], '')
# runhooks runs all hooks even if not matching by design.
self.assertTrue(re.match(r'^________ running \'.*?python -c '
r'open\(\'src/hooked2\', \'w\'\)\.write\(\'hooked2\'\)\' in \'.*',
out[3]))
self.checkString('', results[1])
self.assertEquals(out[3], '? third_party/foo')
self.assertEquals('', results[1])
self.assertEquals(0, results[2])
class GClientSmokeGIT(GClientSmokeBase):
def testSync(self):
def testSyncGit(self):
"""Test pure gclient git checkout, example of Chromium OS checkout"""
self.gclient(['config', self.git_base + 'repo_1', '--name', 'src'])
# Test unversioned checkout.
results = self.gclient(['sync', '--deps', 'mac'])
out = results[0].splitlines(False)
# TODO(maruel): http://crosbug.com/3582 hooks run even if not matching, must
# add sync parsing to get the list of updated files.
self.assertEquals(13, len(out))
logging.debug(results[0])
self.assertTrue(results[1].startswith('Switched to a new branch \''))
self.assertEquals(0, results[2])
tree = mangle_git_tree(
......@@ -301,21 +255,14 @@ class GClientSmokeGIT(GClientSmokeBase):
(join('src', 'repo2'), FAKE.git_hashes['repo_2'][0][1]),
(join('src', 'repo2', 'repo_renamed'), FAKE.git_hashes['repo_3'][1][1]),
)
tree[join('src', 'hooked1')] = 'hooked1'
tree[join('src', 'hooked2')] = 'hooked2'
self.assertTree(tree)
# Manually remove hooked1 before synching to make sure it's not recreated.
os.remove(join(self.root_dir, 'src', 'hooked1'))
# Test incremental versioned sync: sync backward.
results = self.gclient(['sync', '--revision',
'src@' + FAKE.git_hashes['repo_1'][0][0],
'--deps', 'mac', '--delete_unversioned_trees'])
logging.debug(results[0])
out = results[0].splitlines(False)
self.assertEquals(20, len(out))
self.checkString('', results[1])
self.assertEquals('', results[1])
self.assertEquals(0, results[2])
tree = mangle_git_tree(
('src', FAKE.git_hashes['repo_1'][0][1]),
......@@ -323,14 +270,11 @@ class GClientSmokeGIT(GClientSmokeBase):
(join('src', 'repo2', 'repo3'), FAKE.git_hashes['repo_3'][1][1]),
(join('src', 'repo4'), FAKE.git_hashes['repo_4'][1][1]),
)
tree[join('src', 'hooked2')] = 'hooked2'
self.assertTree(tree)
# Test incremental sync: delete-unversioned_trees isn't there.
results = self.gclient(['sync', '--deps', 'mac'])
logging.debug(results[0])
out = results[0].splitlines(False)
self.assertEquals(25, len(out))
self.checkString('', results[1])
self.assertEquals('', results[1])
self.assertEquals(0, results[2])
tree = mangle_git_tree(
('src', FAKE.git_hashes['repo_1'][1][1]),
......@@ -339,66 +283,42 @@ class GClientSmokeGIT(GClientSmokeBase):
(join('src', 'repo2', 'repo_renamed'), FAKE.git_hashes['repo_3'][1][1]),
(join('src', 'repo4'), FAKE.git_hashes['repo_4'][1][1]),
)
tree[join('src', 'hooked1')] = 'hooked1'
tree[join('src', 'hooked2')] = 'hooked2'
self.assertTree(tree)
def testRevertAndStatus(self):
"""TODO(maruel): Remove this line once this test is fixed."""
self.gclient(['config', self.git_base + 'repo_1', '--name', 'src'])
# Tested in testSync.
self.gclient(['sync', '--deps', 'mac'])
results = self.gclient(['sync', '--deps', 'mac'])
write(join(self.root_dir, 'src', 'repo2', 'hi'), 'Hey!')
results = self.gclient(['status'])
out = results[0].splitlines(False)
# TODO(maruel): http://crosbug.com/3584 It should output the unversioned
# files.
# TODO(maruel): THIS IS WRONG.
self.assertEquals(0, len(out))
# Revert implies --force implies running hooks without looking at pattern
# matching.
results = self.gclient(['revert'])
out = results[0].splitlines(False)
# TODO(maruel): http://crosbug.com/3583 It just runs the hooks right now.
self.assertEquals(7, len(out))
self.checkString('', results[1])
self.assertEquals('', results[1])
self.assertEquals(0, results[2])
tree = mangle_git_tree(
('src', FAKE.git_hashes['repo_1'][1][1]),
(join('src', 'repo2'), FAKE.git_hashes['repo_2'][0][1]),
(join('src', 'repo2', 'repo_renamed'), FAKE.git_hashes['repo_3'][1][1]),
)
# TODO(maruel): http://crosbug.com/3583 This file should have been removed.
# TODO(maruel): THIS IS WRONG.
tree[join('src', 'repo2', 'hi')] = 'Hey!'
tree[join('src', 'hooked1')] = 'hooked1'
tree[join('src', 'hooked2')] = 'hooked2'
self.assertTree(tree)
results = self.gclient(['status'])
out = results[0].splitlines(False)
# TODO(maruel): http://crosbug.com/3584 It should output the unversioned
# files.
# TODO(maruel): THIS IS WRONG.
self.assertEquals(0, len(out))
def testRunHooks(self):
self.gclient(['config', self.git_base + 'repo_1', '--name', 'src'])
self.gclient(['sync', '--deps', 'mac'])
results = self.gclient(['runhooks'])
logging.debug(results[0])
out = results[0].splitlines(False)
self.assertEquals(4, len(out))
self.assertEquals(out[0], '')
self.assertTrue(re.match(r'^________ running \'.*?python -c '
r'open\(\'src/hooked1\', \'w\'\)\.write\(\'hooked1\'\)\' in \'.*',
out[1]))
self.assertEquals(out[2], '')
# runhooks runs all hooks even if not matching by design.
self.assertTrue(re.match(r'^________ running \'.*?python -c '
r'open\(\'src/hooked2\', \'w\'\)\.write\(\'hooked2\'\)\' in \'.*',
out[3]))
self.checkString('', results[1])
self.assertEquals(0, results[2])
class GClientSmokeRevInfo(GClientSmokeBase):
"""revert is the second most important command. Hence test it more."""
def setUp(self):
GClientSmokeBase.setUp(self)
self.gclient(['config', self.URL_BASE])
if __name__ == '__main__':
......
#!/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