diff --git a/gclient.py b/gclient.py index 386b1a916..bc70ccb81 100755 --- a/gclient.py +++ b/gclient.py @@ -554,7 +554,7 @@ class GClient(object): raise Error( "relative DEPS entry \"%s\" must begin with a slash" % d) # Create a scm just to query the full url. - scm = gclient_scm.create_scm(solution["url"], self._root_dir, + scm = gclient_scm.SCMWrapper(solution["url"], self._root_dir, None) url = scm.FullUrlForRelativeUrl(url) if d in deps and deps[d] != url: @@ -671,7 +671,7 @@ class GClient(object): entries[name] = url if run_scm: self._options.revision = revision_overrides.get(name) - scm = gclient_scm.create_scm(url, self._root_dir, name) + scm = gclient_scm.SCMWrapper(url, self._root_dir, name) scm.RunCommand(command, self._options, args, file_list) file_list = [os.path.join(name, file.strip()) for file in file_list] self._options.revision = None @@ -697,7 +697,7 @@ class GClient(object): entries[d] = url if run_scm: self._options.revision = revision_overrides.get(d) - scm = gclient_scm.create_scm(url, self._root_dir, d) + scm = gclient_scm.SCMWrapper(url, self._root_dir, d) scm.RunCommand(command, self._options, args, file_list) self._options.revision = None @@ -714,7 +714,7 @@ class GClient(object): entries[d] = url if run_scm: self._options.revision = revision_overrides.get(d) - scm = gclient_scm.create_scm(url, self._root_dir, d) + scm = gclient_scm.SCMWrapper(url, self._root_dir, d) scm.RunCommand(command, self._options, args, file_list) self._options.revision = None diff --git a/gclient_scm.py b/gclient_scm.py index 43eaca772..148855c89 100644 --- a/gclient_scm.py +++ b/gclient_scm.py @@ -27,31 +27,23 @@ SVN_COMMAND = "svn" ### SCM abstraction layer -# Factory Method for SCM wrapper creation - -def create_scm(url, root_dir, relpath, scm_name='svn'): - # TODO(maruel): Deduce the SCM from the url. - scm_map = { - 'svn' : SVNWrapper, - } - if not scm_name in scm_map: - raise gclient_utils.Error('Unsupported scm %s' % scm_name) - return scm_map[scm_name](url, root_dir, relpath, scm_name) - - -# SCMWrapper base class - class SCMWrapper(object): """Add necessary glue between all the supported SCM. This is the abstraction layer to bind to different SCM. Since currently only subversion is supported, a lot of subersionism remains. This can be sorted out once another SCM is supported.""" - def __init__(self, url, root_dir, relpath, scm_name='svn'): + def __init__(self, url=None, root_dir=None, relpath=None, + scm_name='svn'): + # TODO(maruel): Deduce the SCM from the url. self.scm_name = scm_name self.url = url - self._root_dir = root_dir.replace('/', os.sep) - self.relpath = relpath.replace('/', os.sep) + self._root_dir = root_dir + if self._root_dir: + self._root_dir = self._root_dir.replace('/', os.sep) + self.relpath = relpath + if self.relpath: + self.relpath = self.relpath.replace('/', os.sep) def FullUrlForRelativeUrl(self, url): # Find the forth '/' and strip from there. A bit hackish. @@ -62,21 +54,21 @@ class SCMWrapper(object): if file_list is None: file_list = [] - commands = ['cleanup', 'export', 'update', 'revert', - 'status', 'diff', 'pack', 'runhooks'] + commands = { + 'cleanup': self.cleanup, + 'export': self.export, + 'update': self.update, + 'revert': self.revert, + 'status': self.status, + 'diff': self.diff, + 'pack': self.pack, + 'runhooks': self.status, + } if not command in commands: raise gclient_utils.Error('Unknown command %s' % command) - if not command in dir(self): - raise gclient_utils.Error('Command %s not implemnted in %s wrapper' % ( - command, self.scm_name)) - - return getattr(self, command)(options, args, file_list) - - -class SVNWrapper(SCMWrapper): - """ Wrapper for SVN """ + return commands[command](options, args, file_list) def cleanup(self, options, args, file_list): """Cleanup working copy.""" @@ -266,9 +258,6 @@ class SVNWrapper(SCMWrapper): RunSVN(command + accumulated_paths, os.path.join(self._root_dir, self.relpath)) - def runhooks(self, options, args, file_list): - self.status(options, args, file_list) - def status(self, options, args, file_list): """Display status information.""" path = os.path.join(self._root_dir, self.relpath) diff --git a/tests/gclient_test.py b/tests/gclient_test.py index d61aca372..8d9295cd2 100644 --- a/tests/gclient_test.py +++ b/tests/gclient_test.py @@ -70,12 +70,12 @@ class GClientBaseTestCase(BaseTestCase): self.mox.StubOutWithMock(gclient_scm, 'RunSVNAndGetFileList') self._gclient_gclient = gclient.GClient gclient.GClient = self.mox.CreateMockAnything() - self._scm_wrapper = gclient_scm.create_scm - gclient_scm.create_scm = self.mox.CreateMockAnything() + self._scm_wrapper = gclient_scm.SCMWrapper + gclient_scm.SCMWrapper = self.mox.CreateMockAnything() def tearDown(self): gclient.GClient = self._gclient_gclient - gclient_scm.create_scm = self._scm_wrapper + gclient_scm.SCMWrapper = self._scm_wrapper BaseTestCase.tearDown(self) @@ -408,7 +408,7 @@ class GClientClassTestCase(GclientTestCase): # An scm will be requested for the solution. scm_wrapper_sol = self.mox.CreateMockAnything() - gclient_scm.create_scm(self.url, self.root_dir, solution_name + gclient_scm.SCMWrapper(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, []) @@ -465,7 +465,7 @@ class GClientClassTestCase(GclientTestCase): ).AndReturn(False) # An scm will be requested for the solution. - gclient_scm.create_scm(self.url, self.root_dir, solution_name + gclient_scm.SCMWrapper(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, []) @@ -477,7 +477,7 @@ class GClientClassTestCase(GclientTestCase): # 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_scm.create_scm( + gclient_scm.SCMWrapper( 'svn://scm.t/trunk', self.root_dir, os.path.join(solution_name, "src", "t")).AndReturn(scm_wrapper_t) @@ -539,7 +539,7 @@ class GClientClassTestCase(GclientTestCase): ).AndReturn(False) # An scm will be requested for the solution. - gclient_scm.create_scm(self.url, self.root_dir, solution_name + gclient_scm.SCMWrapper(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, []) @@ -549,13 +549,13 @@ class GClientClassTestCase(GclientTestCase): # Next we expect an scm to be request for dep src/n even though it does not # exist in the DEPS file. - gclient_scm.create_scm('svn://custom.n/trunk', - self.root_dir, - "src/n").AndReturn(scm_wrapper_n) + gclient_scm.SCMWrapper('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_scm.create_scm('svn://custom.t/trunk', + gclient_scm.SCMWrapper('svn://custom.t/trunk', self.root_dir, "src/t").AndReturn(scm_wrapper_t) @@ -625,7 +625,7 @@ class GClientClassTestCase(GclientTestCase): ).AndReturn(False) # An scm will be requested for the first solution. - gclient_scm.create_scm(url_a, self.root_dir, name_a).AndReturn( + gclient_scm.SCMWrapper(url_a, self.root_dir, name_a).AndReturn( scm_wrapper_a) # Then an attempt will be made to read it's DEPS file. gclient.FileRead(os.path.join(self.root_dir, name_a, options.deps_file) @@ -634,7 +634,7 @@ class GClientClassTestCase(GclientTestCase): scm_wrapper_a.RunCommand('update', options, self.args, []) # An scm will be requested for the second solution. - gclient_scm.create_scm(url_b, self.root_dir, name_b).AndReturn( + gclient_scm.SCMWrapper(url_b, self.root_dir, name_b).AndReturn( scm_wrapper_b) # Then an attempt will be made to read its DEPS file. gclient.FileRead(os.path.join(self.root_dir, name_b, options.deps_file) @@ -643,7 +643,7 @@ class GClientClassTestCase(GclientTestCase): scm_wrapper_b.RunCommand('update', options, self.args, []) # Finally, an scm is requested for the shared dep. - gclient_scm.create_scm('http://svn.t/trunk', self.root_dir, 'src/t' + gclient_scm.SCMWrapper('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, []) @@ -671,9 +671,9 @@ class GClientClassTestCase(GclientTestCase): ).AndReturn(False) gclient.os.path.exists(os.path.join(self.root_dir, options.entries_filename) ).AndReturn(False) - gclient_scm.create_scm(self.url, self.root_dir, name).AndReturn( - gclient_scm.create_scm) - gclient_scm.create_scm.RunCommand('update', options, self.args, []) + gclient_scm.SCMWrapper(self.url, self.root_dir, name).AndReturn( + gclient_scm.SCMWrapper) + gclient_scm.SCMWrapper.RunCommand('update', options, self.args, []) gclient.FileRead(os.path.join(self.root_dir, name, options.deps_file) ).AndReturn("Boo = 'a'") gclient.FileWrite(os.path.join(self.root_dir, options.entries_filename), @@ -765,36 +765,36 @@ deps_os = { gclient.os.path.exists(os.path.join(self.root_dir, options.entries_filename) ).AndReturn(False) - gclient_scm.create_scm(self.url, self.root_dir, 'src').AndReturn( + gclient_scm.SCMWrapper(self.url, self.root_dir, 'src').AndReturn( scm_wrapper_src) scm_wrapper_src.RunCommand('update', mox.Func(OptIsRev123), self.args, []) - gclient_scm.create_scm(self.url, self.root_dir, + gclient_scm.SCMWrapper(self.url, self.root_dir, None).AndReturn(scm_wrapper_src2) scm_wrapper_src2.FullUrlForRelativeUrl('/trunk/deps/third_party/cygwin@3248' ).AndReturn(cygwin_path) - gclient_scm.create_scm(self.url, self.root_dir, + gclient_scm.SCMWrapper(self.url, self.root_dir, None).AndReturn(scm_wrapper_src2) scm_wrapper_src2.FullUrlForRelativeUrl('/trunk/deps/third_party/WebKit' ).AndReturn(webkit_path) - gclient_scm.create_scm(webkit_path, self.root_dir, + gclient_scm.SCMWrapper(webkit_path, self.root_dir, 'foo/third_party/WebKit').AndReturn(scm_wrapper_webkit) scm_wrapper_webkit.RunCommand('update', mox.Func(OptIsRev42), self.args, []) - gclient_scm.create_scm( + gclient_scm.SCMWrapper( '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_scm.create_scm(cygwin_path, self.root_dir, + gclient_scm.SCMWrapper(cygwin_path, self.root_dir, 'src/third_party/cygwin').AndReturn(scm_wrapper_cygwin) scm_wrapper_cygwin.RunCommand('update', mox.Func(OptIsRev333), self.args, []) - gclient_scm.create_scm('svn://random_server:123/trunk/python_24@5580', + gclient_scm.SCMWrapper('svn://random_server:123/trunk/python_24@5580', self.root_dir, 'src/third_party/python_24').AndReturn( scm_wrapper_python) @@ -870,18 +870,18 @@ deps = { ).AndReturn(False) gclient.os.path.exists(os.path.join(self.root_dir, options.entries_filename) ).AndReturn(False) - gclient_scm.create_scm(self.url, self.root_dir, name).AndReturn( - gclient_scm.create_scm) - gclient_scm.create_scm.RunCommand('update', options, self.args, []) + gclient_scm.SCMWrapper(self.url, self.root_dir, name).AndReturn( + gclient_scm.SCMWrapper) + gclient_scm.SCMWrapper.RunCommand('update', options, self.args, []) - gclient_scm.create_scm(self.url, self.root_dir, + gclient_scm.SCMWrapper(self.url, self.root_dir, None).AndReturn(scm_wrapper_src) scm_wrapper_src.FullUrlForRelativeUrl('/trunk/bar/WebKit' ).AndReturn(webkit_path) - gclient_scm.create_scm(webkit_path, self.root_dir, - 'foo/third_party/WebKit').AndReturn(gclient_scm.create_scm) - gclient_scm.create_scm.RunCommand('update', options, self.args, []) + gclient_scm.SCMWrapper(webkit_path, self.root_dir, + 'foo/third_party/WebKit').AndReturn(gclient_scm.SCMWrapper) + gclient_scm.SCMWrapper.RunCommand('update', options, self.args, []) self.mox.ReplayAll() client = self._gclient_gclient(self.root_dir, options) @@ -926,18 +926,18 @@ deps = { ).AndReturn(False) gclient.os.path.exists(os.path.join(self.root_dir, options.entries_filename) ).AndReturn(False) - gclient_scm.create_scm(self.url, self.root_dir, name).AndReturn( - gclient_scm.create_scm) - gclient_scm.create_scm.RunCommand('update', options, self.args, []) + gclient_scm.SCMWrapper(self.url, self.root_dir, name).AndReturn( + gclient_scm.SCMWrapper) + gclient_scm.SCMWrapper.RunCommand('update', options, self.args, []) - gclient_scm.create_scm(self.url, self.root_dir, + gclient_scm.SCMWrapper(self.url, self.root_dir, None).AndReturn(scm_wrapper_src) scm_wrapper_src.FullUrlForRelativeUrl('/trunk/bar_custom/WebKit' ).AndReturn(webkit_path) - gclient_scm.create_scm(webkit_path, self.root_dir, - 'foo/third_party/WebKit').AndReturn(gclient_scm.create_scm) - gclient_scm.create_scm.RunCommand('update', options, self.args, []) + gclient_scm.SCMWrapper(webkit_path, self.root_dir, + 'foo/third_party/WebKit').AndReturn(gclient_scm.SCMWrapper) + gclient_scm.SCMWrapper.RunCommand('update', options, self.args, []) self.mox.ReplayAll() client = self._gclient_gclient(self.root_dir, options) @@ -961,9 +961,9 @@ deps = { options = self.Options() gclient.FileRead(os.path.join(self.root_dir, name, options.deps_file) ).AndReturn(deps_content) - gclient_scm.create_scm(self.url, self.root_dir, name).AndReturn( - gclient_scm.create_scm) - gclient_scm.create_scm.RunCommand('update', options, self.args, []) + gclient_scm.SCMWrapper(self.url, self.root_dir, name).AndReturn( + gclient_scm.SCMWrapper) + gclient_scm.SCMWrapper.RunCommand('update', options, self.args, []) self.mox.ReplayAll() client = self._gclient_gclient(self.root_dir, options) @@ -1038,27 +1038,18 @@ class SCMWrapperTestCase(GClientBaseTestCase): def testDir(self): members = [ 'FullUrlForRelativeUrl', 'RunCommand', 'cleanup', 'diff', 'export', - 'pack', 'relpath', 'revert', 'runhooks', 'scm_name', 'status', - 'update', 'url', + 'pack', 'relpath', 'revert', 'scm_name', 'status', 'update', 'url', ] # If you add a member, be sure to add the relevant test! - self.compareMembers(self._scm_wrapper(self.url, - self.root_dir, - self.relpath), - members) - - def testUnsupportedSCM(self): - args = [self.url, self.root_dir, self.relpath] - kwargs = {'scm_name' : 'foo'} - exception_msg = 'Unsupported scm %(scm_name)s' % kwargs - self.assertRaisesError(exception_msg, self._scm_wrapper, *args, **kwargs) + self.compareMembers(self._scm_wrapper(), members) def testFullUrlForRelativeUrl(self): self.url = 'svn://a/b/c/d' self.mox.ReplayAll() - scm = self._scm_wrapper(self.url, self.root_dir, self.relpath) + scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir, + relpath=self.relpath) self.assertEqual(scm.FullUrlForRelativeUrl('/crap'), 'svn://a/b/crap') def testRunCommandException(self): @@ -1067,10 +1058,11 @@ class SCMWrapperTestCase(GClientBaseTestCase): ).AndReturn(False) self.mox.ReplayAll() - scm = self._scm_wrapper(self.url, self.root_dir, self.relpath) + scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir, + relpath=self.relpath) exception = "Unsupported argument(s): %s" % ','.join(self.args) - self.assertRaisesError(exception, scm.RunCommand, - 'update', options, self.args) + self.assertRaisesError(exception, self._scm_wrapper.RunCommand, + scm, 'update', options, self.args) def testRunCommandUnknown(self): # TODO(maruel): if ever used. @@ -1090,7 +1082,8 @@ class SCMWrapperTestCase(GClientBaseTestCase): self.root_dir, files_list) self.mox.ReplayAll() - scm = self._scm_wrapper(self.url, self.root_dir, self.relpath) + scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir, + relpath=self.relpath) scm.revert(options, self.args, files_list) def testRevertNone(self): @@ -1100,7 +1093,8 @@ class SCMWrapperTestCase(GClientBaseTestCase): gclient_scm.CaptureSVNStatus(base_path).AndReturn([]) self.mox.ReplayAll() - scm = self._scm_wrapper(self.url, self.root_dir, self.relpath) + scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir, + relpath=self.relpath) file_list = [] scm.revert(options, self.args, file_list) @@ -1119,7 +1113,8 @@ class SCMWrapperTestCase(GClientBaseTestCase): gclient_scm.RunSVN(['revert', 'a', 'b'], base_path) self.mox.ReplayAll() - scm = self._scm_wrapper(self.url, self.root_dir, self.relpath) + scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir, + relpath=self.relpath) file_list = [] scm.revert(options, self.args, file_list) self.assertEquals(sorted(file_list), sorted([os.path.join(base_path, 'a'), @@ -1155,7 +1150,8 @@ class SCMWrapperTestCase(GClientBaseTestCase): []).AndReturn(None) self.mox.ReplayAll() - scm = self._scm_wrapper(self.url, self.root_dir, self.relpath) + scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir, + relpath=self.relpath) file_list = [] self.assertEqual(scm.status(options, self.args, file_list), None) @@ -1177,7 +1173,8 @@ class SCMWrapperTestCase(GClientBaseTestCase): gclient_scm.RunSVNAndGetFileList(['checkout', self.url, base_path], self.root_dir, files_list) self.mox.ReplayAll() - scm = self._scm_wrapper(self.url, self.root_dir, self.relpath) + scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir, + relpath=self.relpath) scm.update(options, (), files_list) def testUpdateUpdate(self): @@ -1206,7 +1203,8 @@ class SCMWrapperTestCase(GClientBaseTestCase): self.root_dir, files_list) self.mox.ReplayAll() - scm = self._scm_wrapper(self.url, self.root_dir, self.relpath) + scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir, + relpath=self.relpath) scm.update(options, (), files_list) def testUpdateGit(self): @@ -1216,7 +1214,8 @@ class SCMWrapperTestCase(GClientBaseTestCase): print("________ found .git directory; skipping %s" % self.relpath) self.mox.ReplayAll() - scm = self._scm_wrapper(self.url, self.root_dir, self.relpath) + scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir, + relpath=self.relpath) file_list = [] scm.update(options, self.args, file_list)