changeset 241:4950b18cf949

Move fetch_command.fetch_revisions() to svncommands.pull().
author Dirkjan Ochtman <dirkjan@ochtman.nl>
date Wed, 08 Apr 2009 17:49:30 +0200
parents 1aa1d2d406d9
children 06130689a2c8
files __init__.py cmdutil.py fetch_command.py push_cmd.py svncommand.py svncommands.py tests/comprehensive/test_stupid_pull.py tests/test_fetch_mappings.py tests/test_fetch_truncated.py tests/test_push_command.py tests/test_util.py tests/test_utility_commands.py
diffstat 12 files changed, 164 insertions(+), 189 deletions(-) [+]
line wrap: on
line diff
--- a/__init__.py
+++ b/__init__.py
@@ -21,7 +21,7 @@ from mercurial import util as mutil
 from svn import core
 
 import svncommand
-import fetch_command
+import svncommands
 import tag_repo
 import util
 
@@ -58,7 +58,7 @@ def svn_fetch(ui, svn_url, hg_repo_path=
     should_update = not os.path.exists(hg_repo_path)
     svn_url = util.normalize_url(svn_url)
     try:
-        res = fetch_command.fetch_revisions(ui, svn_url, hg_repo_path, **opts)
+        res = svncommands.pull(ui, svn_url, hg_repo_path, **opts)
     except core.SubversionException, e:
         if e.apr_err == core.SVN_ERR_RA_SERF_SSL_CERT_UNTRUSTED:
             raise mutil.Abort('It appears svn does not trust the ssl cert for this site.\n'
new file mode 100644
--- /dev/null
+++ b/cmdutil.py
@@ -0,0 +1,32 @@
+
+def replay_convert_rev(hg_editor, svn, r):
+    hg_editor.set_current_rev(r)
+    svn.get_replay(r.revnum, hg_editor)
+    i = 1
+    if hg_editor.missing_plaintexts:
+        hg_editor.ui.debug('Fetching %s files that could not use replay.\n' %
+                           len(hg_editor.missing_plaintexts))
+        files_to_grab = set()
+        rootpath = svn.subdir and svn.subdir[1:] or ''
+        for p in hg_editor.missing_plaintexts:
+            hg_editor.ui.note('.')
+            hg_editor.ui.flush()
+            if p[-1] == '/':
+                dirpath = p[len(rootpath):]
+                files_to_grab.update([dirpath + f for f,k in
+                                      svn.list_files(dirpath, r.revnum)
+                                      if k == 'f'])
+            else:
+                files_to_grab.add(p[len(rootpath):])
+        hg_editor.ui.note('\nFetching files...\n')
+        for p in files_to_grab:
+            hg_editor.ui.note('.')
+            hg_editor.ui.flush()
+            if i % 50 == 0:
+                svn.init_ra_and_client()
+            i += 1
+            data, mode = svn.get_file(p, r.revnum)
+            hg_editor.set_file(p, data, 'x' in mode, 'l' in mode)
+        hg_editor.missing_plaintexts = set()
+        hg_editor.ui.note('\n')
+    hg_editor.commit_current_delta()
deleted file mode 100644
--- a/fetch_command.py
+++ /dev/null
@@ -1,132 +0,0 @@
-import os
-
-from mercurial import util as merc_util
-from svn import core
-from svn import delta
-
-import hg_delta_editor
-import svnwrap
-import stupid as stupidmod
-import util
-
-
-def fetch_revisions(ui, svn_url, hg_repo_path, skipto_rev=0, stupid=None,
-                    tag_locations='tags',
-                    authors=None,
-                    filemap=None,
-                    **opts):
-    """pull new revisions from Subversion
-    """
-    svn_url = util.normalize_url(svn_url)
-    old_encoding = util.swap_out_encoding()
-    skipto_rev=int(skipto_rev)
-    have_replay = not stupid
-    if have_replay and not callable(
-        delta.svn_txdelta_apply(None, None, None)[0]): #pragma: no cover
-        ui.status('You are using old Subversion SWIG bindings. Replay will not'
-                  ' work until you upgrade to 1.5.0 or newer. Falling back to'
-                  ' a slower method that may be buggier. Please upgrade, or'
-                  ' contribute a patch to use the ctypes bindings instead'
-                  ' of SWIG.\n')
-        have_replay = False
-    initializing_repo = False
-    user = opts.get('username', merc_util.getuser())
-    passwd = opts.get('password', '')
-    svn = svnwrap.SubversionRepo(svn_url, user, passwd)
-    author_host = "@%s" % svn.uuid
-    tag_locations = tag_locations.split(',')
-    hg_editor = hg_delta_editor.HgChangeReceiver(hg_repo_path,
-                                                 ui_=ui,
-                                                 subdir=svn.subdir,
-                                                 author_host=author_host,
-                                                 tag_locations=tag_locations,
-                                                 authors=authors,
-                                                 filemap=filemap)
-    if os.path.exists(hg_editor.uuid_file):
-        uuid = open(hg_editor.uuid_file).read()
-        assert uuid == svn.uuid
-        start = hg_editor.last_known_revision()
-    else:
-        open(hg_editor.uuid_file, 'w').write(svn.uuid)
-        open(hg_editor.svn_url_file, 'w').write(svn_url)
-        initializing_repo = True
-        start = skipto_rev
-
-    if initializing_repo and start > 0:
-        raise merc_util.Abort('Revision skipping at repository initialization '
-                              'remains unimplemented.')
-
-    # start converting revisions
-    for r in svn.revisions(start=start):
-        valid = True
-        hg_editor.update_branch_tag_map_for_rev(r)
-        for p in r.paths:
-            if hg_editor._is_path_valid(p):
-                valid = True
-                break
-        if valid:
-            # got a 502? Try more than once!
-            tries = 0
-            converted = False
-            while not converted:
-                try:
-                    util.describe_revision(ui, r)
-                    if have_replay:
-                        try:
-                            replay_convert_rev(hg_editor, svn, r)
-                        except svnwrap.SubversionRepoCanNotReplay, e: #pragma: no cover
-                            ui.status('%s\n' % e.message)
-                            stupidmod.print_your_svn_is_old_message(ui)
-                            have_replay = False
-                            stupidmod.svn_server_pull_rev(ui, svn, hg_editor, r)
-                    else:
-                        stupidmod.svn_server_pull_rev(ui, svn, hg_editor, r)
-                    converted = True
-                except core.SubversionException, e: #pragma: no cover
-                    if (e.apr_err == core.SVN_ERR_RA_DAV_REQUEST_FAILED
-                        and '502' in str(e)
-                        and tries < 3):
-                        tries += 1
-                        ui.status('Got a 502, retrying (%s)\n' % tries)
-                    else:
-                        raise merc_util.Abort(*e.args)
-    util.swap_out_encoding(old_encoding)
-
-fetch_revisions = util.register_subcommand('pull')(fetch_revisions)
-
-
-def cleanup_file_handles(svn, count):
-    if count % 50 == 0:
-        svn.init_ra_and_client()
-
-
-def replay_convert_rev(hg_editor, svn, r):
-    hg_editor.set_current_rev(r)
-    svn.get_replay(r.revnum, hg_editor)
-    i = 1
-    if hg_editor.missing_plaintexts:
-        hg_editor.ui.debug('Fetching %s files that could not use replay.\n' %
-                           len(hg_editor.missing_plaintexts))
-        files_to_grab = set()
-        rootpath = svn.subdir and svn.subdir[1:] or ''
-        for p in hg_editor.missing_plaintexts:
-            hg_editor.ui.note('.')
-            hg_editor.ui.flush()
-            if p[-1] == '/':
-                dirpath = p[len(rootpath):]
-                files_to_grab.update([dirpath + f for f,k in
-                                      svn.list_files(dirpath, r.revnum)
-                                      if k == 'f'])
-            else:
-                files_to_grab.add(p[len(rootpath):])
-        hg_editor.ui.note('\nFetching files...\n')
-        for p in files_to_grab:
-            hg_editor.ui.note('.')
-            hg_editor.ui.flush()
-            cleanup_file_handles(svn, i)
-            i += 1
-            data, mode = svn.get_file(p, r.revnum)
-            hg_editor.set_file(p, data, 'x' in mode, 'l' in mode)
-        hg_editor.missing_plaintexts = set()
-        hg_editor.ui.note('\n')
-    hg_editor.commit_current_delta()
--- a/push_cmd.py
+++ b/push_cmd.py
@@ -7,7 +7,7 @@ import util
 import hg_delta_editor
 import svnexternals
 import svnwrap
-import fetch_command
+import svncommands
 import utility_commands
 
 
@@ -68,9 +68,8 @@ def push_revisions_to_subversion(ui, rep
                      old_ctx)
             return 1
         # 3. Fetch revisions from svn
-        r = fetch_command.fetch_revisions(ui, svn_url, hg_repo_path,
-                                          stupid=stupid, username=user,
-                                          password=passwd)
+        r = svncommands.pull(ui, svn_url, hg_repo_path, stupid=stupid,
+                             username=user, password=passwd)
         assert not r or r == 0
         # 4. Find the new head of the target branch
         repo = hg.repository(ui, hge.path)
--- a/svncommand.py
+++ b/svncommand.py
@@ -10,13 +10,13 @@ import svnwrap
 import util
 from util import register_subcommand, svn_subcommands, generate_help, svn_commands_nourl
 # dirty trick to force demandimport to run my decorator anyway.
+from svncommands import pull
 from utility_commands import print_wc_url
-from fetch_command import fetch_revisions
 from push_cmd import commit_from_rev
 from diff_cmd import diff_command
 from rebuildmeta import rebuildmeta
 # shut up, pyflakes, we must import those
-__x = [print_wc_url, fetch_revisions, commit_from_rev, diff_command, rebuildmeta]
+__x = [print_wc_url, pull, commit_from_rev, diff_command, rebuildmeta]
 
 
 def svncmd(ui, repo, subcommand, *args, **opts):
new file mode 100644
--- /dev/null
+++ b/svncommands.py
@@ -0,0 +1,93 @@
+import os
+
+from mercurial import util as hgutil
+from svn import core
+from svn import delta
+
+import hg_delta_editor
+import svnwrap
+import stupid as stupidmod
+import cmdutil
+import util
+
+
+def pull(ui, svn_url, hg_repo_path, skipto_rev=0, stupid=None,
+         tag_locations='tags', authors=None, filemap=None, **opts):
+    """pull new revisions from Subversion
+    """
+    svn_url = util.normalize_url(svn_url)
+    old_encoding = util.swap_out_encoding()
+    skipto_rev=int(skipto_rev)
+    have_replay = not stupid
+    if have_replay and not callable(
+        delta.svn_txdelta_apply(None, None, None)[0]): #pragma: no cover
+        ui.status('You are using old Subversion SWIG bindings. Replay will not'
+                  ' work until you upgrade to 1.5.0 or newer. Falling back to'
+                  ' a slower method that may be buggier. Please upgrade, or'
+                  ' contribute a patch to use the ctypes bindings instead'
+                  ' of SWIG.\n')
+        have_replay = False
+    initializing_repo = False
+    user = opts.get('username', hgutil.getuser())
+    passwd = opts.get('password', '')
+    svn = svnwrap.SubversionRepo(svn_url, user, passwd)
+    author_host = "@%s" % svn.uuid
+    tag_locations = tag_locations.split(',')
+    hg_editor = hg_delta_editor.HgChangeReceiver(hg_repo_path,
+                                                 ui_=ui,
+                                                 subdir=svn.subdir,
+                                                 author_host=author_host,
+                                                 tag_locations=tag_locations,
+                                                 authors=authors,
+                                                 filemap=filemap)
+    if os.path.exists(hg_editor.uuid_file):
+        uuid = open(hg_editor.uuid_file).read()
+        assert uuid == svn.uuid
+        start = hg_editor.last_known_revision()
+    else:
+        open(hg_editor.uuid_file, 'w').write(svn.uuid)
+        open(hg_editor.svn_url_file, 'w').write(svn_url)
+        initializing_repo = True
+        start = skipto_rev
+
+    if initializing_repo and start > 0:
+        raise hgutil.Abort('Revision skipping at repository initialization '
+                           'remains unimplemented.')
+
+    # start converting revisions
+    for r in svn.revisions(start=start):
+        valid = True
+        hg_editor.update_branch_tag_map_for_rev(r)
+        for p in r.paths:
+            if hg_editor._is_path_valid(p):
+                valid = True
+                break
+        if valid:
+            # got a 502? Try more than once!
+            tries = 0
+            converted = False
+            while not converted:
+                try:
+                    util.describe_revision(ui, r)
+                    if have_replay:
+                        try:
+                            cmdutil.replay_convert_rev(hg_editor, svn, r)
+                        except svnwrap.SubversionRepoCanNotReplay, e: #pragma: no cover
+                            ui.status('%s\n' % e.message)
+                            stupidmod.print_your_svn_is_old_message(ui)
+                            have_replay = False
+                            stupidmod.svn_server_pull_rev(ui, svn, hg_editor, r)
+                    else:
+                        stupidmod.svn_server_pull_rev(ui, svn, hg_editor, r)
+                    converted = True
+                except core.SubversionException, e: #pragma: no cover
+                    if (e.apr_err == core.SVN_ERR_RA_DAV_REQUEST_FAILED
+                        and '502' in str(e)
+                        and tries < 3):
+                        tries += 1
+                        ui.status('Got a 502, retrying (%s)\n' % tries)
+                    else:
+                        raise hgutil.Abort(*e.args)
+    util.swap_out_encoding(old_encoding)
+
+pull = util.register_subcommand('pull')(pull)
--- a/tests/comprehensive/test_stupid_pull.py
+++ b/tests/comprehensive/test_stupid_pull.py
@@ -6,7 +6,7 @@ from mercurial import hg
 from mercurial import ui
 
 from tests import test_util
-import fetch_command
+import svncommands
 
 
 def _do_case(self, name):
@@ -18,10 +18,8 @@ def _do_case(self, name):
     checkout_path = self.repo_path
     if subdir:
         checkout_path += '/' + subdir
-    fetch_command.fetch_revisions(ui.ui(),
-                                  svn_url=test_util.fileurl(checkout_path),
-                                  hg_repo_path=wc2_path,
-                                  stupid=True)
+    svncommands.pull(ui.ui(), svn_url=test_util.fileurl(checkout_path),
+                     hg_repo_path=wc2_path, stupid=True)
     self.repo2 = hg.repository(ui.ui(), wc2_path)
     self.assertEqual(self.repo.branchtags(), self.repo2.branchtags())
     self.assertEqual(pickle.load(open(os.path.join(self.wc_path, '.hg', 'svn', 'tag_info'))),
--- a/tests/test_fetch_mappings.py
+++ b/tests/test_fetch_mappings.py
@@ -7,7 +7,7 @@ from mercurial import ui
 from mercurial import node
 
 import test_util
-import fetch_command
+import svncommands
 
 class MapTests(test_util.TestBase):
     @property
@@ -23,11 +23,9 @@ class MapTests(test_util.TestBase):
         authormap = open(self.authors, 'w')
         authormap.write("Augie=Augie Fackler <durin42@gmail.com>\n")
         authormap.close()
-        fetch_command.fetch_revisions(ui.ui(),
-                                      svn_url=test_util.fileurl(self.repo_path),
-                                      hg_repo_path=self.wc_path,
-                                      stupid=stupid,
-                                      authors=self.authors)
+        svncommands.pull(ui.ui(), svn_url=test_util.fileurl(self.repo_path),
+                         hg_repo_path=self.wc_path, stupid=stupid,
+                         authors=self.authors)
         self.assertEqual(self.repo[0].user(),
                          'Augie Fackler <durin42@gmail.com>')
         self.assertEqual(self.repo['tip'].user(),
@@ -41,11 +39,9 @@ class MapTests(test_util.TestBase):
         authormap = open(self.authors, 'w')
         authormap.write("evil=Testy <test@test>")
         authormap.close()
-        fetch_command.fetch_revisions(ui.ui(),
-                                      svn_url=test_util.fileurl(self.repo_path),
-                                      hg_repo_path=self.wc_path,
-                                      stupid=stupid,
-                                      authors=self.authors)
+        svncommands.pull(ui.ui(), svn_url=test_util.fileurl(self.repo_path),
+                         hg_repo_path=self.wc_path, stupid=stupid,
+                         authors=self.authors)
         self.assertEqual(self.repo[0].user(),
                          'Augie@5b65bade-98f3-4993-a01f-b7a6710da339')
         self.assertEqual(self.repo['tip'].user(),
@@ -59,11 +55,9 @@ class MapTests(test_util.TestBase):
         filemap = open(self.filemap, 'w')
         filemap.write("include alpha\n")
         filemap.close()
-        fetch_command.fetch_revisions(ui.ui(),
-                                      svn_url=test_util.fileurl(self.repo_path),
-                                      hg_repo_path=self.wc_path,
-                                      stupid=stupid,
-                                      filemap=self.filemap)
+        svncommands.pull(ui.ui(), svn_url=test_util.fileurl(self.repo_path),
+                         hg_repo_path=self.wc_path, stupid=stupid,
+                         filemap=self.filemap)
         self.assertEqual(node.hex(self.repo[0].node()), '88e2c7492d83e4bf30fbb2dcbf6aa24d60ac688d')
         self.assertEqual(node.hex(self.repo['default'].node()), 'e524296152246b3837fe9503c83b727075835155')
 
@@ -75,11 +69,9 @@ class MapTests(test_util.TestBase):
         filemap = open(self.filemap, 'w')
         filemap.write("exclude alpha\n")
         filemap.close()
-        fetch_command.fetch_revisions(ui.ui(),
-                                      svn_url=test_util.fileurl(self.repo_path),
-                                      hg_repo_path=self.wc_path,
-                                      stupid=stupid,
-                                      filemap=self.filemap)
+        svncommands.pull(ui.ui(), svn_url=test_util.fileurl(self.repo_path),
+                         hg_repo_path=self.wc_path, stupid=stupid,
+                         filemap=self.filemap)
         self.assertEqual(node.hex(self.repo[0].node()), '2c48f3525926ab6c8b8424bcf5eb34b149b61841')
         self.assertEqual(node.hex(self.repo['default'].node()), 'b37a3c0297b71f989064d9b545b5a478bbed7cc1')
 
--- a/tests/test_fetch_truncated.py
+++ b/tests/test_fetch_truncated.py
@@ -3,7 +3,7 @@ import unittest
 from mercurial import hg
 from mercurial import ui
 
-import fetch_command
+import svncommands
 import test_util
 
 class TestFetchTruncatedHistory(test_util.TestBase):
@@ -11,10 +11,8 @@ class TestFetchTruncatedHistory(test_uti
         # Test repository does not follow the usual layout
         test_util.load_svndump_fixture(self.repo_path, 'truncatedhistory.svndump')
         svn_url = test_util.fileurl(self.repo_path + '/project2')
-        fetch_command.fetch_revisions(ui.ui(),
-                                      svn_url=svn_url,
-                                      hg_repo_path=self.wc_path,
-                                      stupid=stupid)
+        svncommands.pull(ui.ui(), svn_url=svn_url,
+                         hg_repo_path=self.wc_path, stupid=stupid)
         repo = hg.repository(ui.ui(), self.wc_path)
 
         # We are converting /project2/trunk coming from:
--- a/tests/test_push_command.py
+++ b/tests/test_push_command.py
@@ -9,7 +9,7 @@ from mercurial import node
 from mercurial import ui
 from mercurial import revlog
 
-import fetch_command
+import svncommands
 import push_cmd
 import test_util
 import time
@@ -38,9 +38,8 @@ class PushOverSvnserveTests(test_util.Te
         args = ['svnserve', '-d', '--foreground', '-r', self.repo_path]
         self.svnserve_pid = subprocess.Popen(args).pid
         time.sleep(2)
-        fetch_command.fetch_revisions(ui.ui(),
-                                      svn_url='svn://localhost/',
-                                      hg_repo_path=self.wc_path)
+        svncommands.pull(ui.ui(), svn_url='svn://localhost/',
+                         hg_repo_path=self.wc_path)
 
     def tearDown(self):
         os.system('kill -9 %d' % self.svnserve_pid)
--- a/tests/test_util.py
+++ b/tests/test_util.py
@@ -13,7 +13,7 @@ from mercurial import hg
 from mercurial import node
 from mercurial import ui
 
-import fetch_command
+import svncommands
 import push_cmd
 
 # Fixtures that need to be pulled at a subdirectory of the repo path
@@ -49,10 +49,8 @@ def load_fixture_and_fetch(fixture_name,
     load_svndump_fixture(repo_path, fixture_name)
     if subdir:
         repo_path += '/' + subdir
-    fetch_command.fetch_revisions(ui.ui(),
-                                  svn_url=fileurl(repo_path),
-                                  hg_repo_path=wc_path,
-                                  stupid=stupid)
+    svncommands.pull(ui.ui(), svn_url=fileurl(repo_path),
+                     hg_repo_path=wc_path, stupid=stupid)
     repo = hg.repository(ui.ui(), wc_path)
     return repo
 
--- a/tests/test_utility_commands.py
+++ b/tests/test_utility_commands.py
@@ -8,7 +8,7 @@ from mercurial import context
 from mercurial import node
 
 import utility_commands
-import fetch_command
+import svncommands
 import test_util
 
 expected_info_output = '''URL: %(repourl)s/%(branch)s
@@ -145,10 +145,9 @@ class UtilityTests(test_util.TestBase):
         """Verify url gets normalized on initial clone.
         """
         test_util.load_svndump_fixture(self.repo_path, 'two_revs.svndump')
-        fetch_command.fetch_revisions(ui.ui(),
-                                      svn_url=test_util.fileurl(self.repo_path)+'/',
-                                      hg_repo_path=self.wc_path,
-                                      stupid=False)
+        svncommands.pull(ui.ui(),
+                         svn_url=test_util.fileurl(self.repo_path) + '/',
+                         hg_repo_path=self.wc_path, stupid=False)
         hg.update(self.repo, 'tip')
         u = ui.ui()
         utility_commands.print_wc_url(u, self.repo, self.wc_path)
@@ -159,10 +158,9 @@ class UtilityTests(test_util.TestBase):
         """Verify url gets normalized on initial clone.
         """
         test_util.load_svndump_fixture(self.repo_path, 'ignores.svndump')
-        fetch_command.fetch_revisions(ui.ui(),
-                                      svn_url=test_util.fileurl(self.repo_path)+'/',
-                                      hg_repo_path=self.wc_path,
-                                      stupid=False)
+        svncommands.pull(ui.ui(),
+                         svn_url=test_util.fileurl(self.repo_path) + '/',
+                         hg_repo_path=self.wc_path, stupid=False)
         hg.update(self.repo, 'tip')
         u = ui.ui()
         utility_commands.generate_ignore(u, self.repo, self.wc_path)