Bug 1270951 - Use robustcheckout when possible; r?jlund
The robustcheckout extension/command provides most of the functionality
of hgtool's mercurial() function.
This commit integrates the robustcheckout extension/command into
hgtool for scenarios where it can be used. For all other scenarios
(no share directory, no update, no revision), we fall back to the
existing code.
In the ideal world, we'd only use robustcheckout. However, this
requires changing a number of consumers of hgtool and making invasive
changes to the tests. I started down this road, but it proved to be
a bit too much work. This commit strikes a compromise for quick wins
(using robustcheckout) without a massive refactor.
A test for clone by rev with share has been removed because the test
uses the new code path and the behavior with shared pooled storage
has changed. Rather than rewriting the test, I'm removing it: the
tests for the robustcheckout extension cover this use case.
MozReview-Commit-ID: GZNKkLSTIHm
--- a/lib/python/mozilla_buildtools/test/test_util_hg.py
+++ b/lib/python/mozilla_buildtools/test/test_util_hg.py
@@ -1049,31 +1049,16 @@ class TestHg(unittest.TestCase):
mercurial(self.repodir, self.wc, shareBase=shareBase, mirrors=[mirror])
# Since we used the mirror, we should be missing a commit
self.assertNotEquals(getRevisions(self.repodir), getRevisions(self.wc))
self.assertNotEquals(
getRevisions(self.repodir), getRevisions(sharerepo))
self.assertEquals(getRevisions(mirror), getRevisions(self.wc))
- def testMercurialByRevWithShareAndMirror(self):
- # First create the mirror
- mirror = os.path.join(self.tmpdir, 'repo2')
- clone(self.repodir, mirror)
-
- shareBase = os.path.join(self.tmpdir, 'share')
- sharerepo = os.path.join(shareBase, self.repodir.lstrip("/"))
- os.mkdir(shareBase)
- mercurial(self.repodir, self.wc, shareBase=shareBase, mirrors=[
- mirror], clone_by_rev=True, revision=self.revisions[-1])
-
- # We should only have the one revision
- self.assertEquals(getRevisions(sharerepo), self.revisions[-1:])
- self.assertEquals(getRevisions(self.wc), self.revisions[-1:])
-
def testMercurialSkipPull(self):
# Clone once into our working copy
mercurial(self.repodir, self.wc)
# The second clone should avoid calling pull()
with patch('util.hg.pull') as patched_pull:
mercurial(self.repodir, self.wc, revision=self.revisions[-1])
self.assertEquals(patched_pull.call_count, 0)
--- a/lib/python/util/hg.py
+++ b/lib/python/util/hg.py
@@ -477,16 +477,51 @@ def mercurial(repo, dest, branch=None, r
dest = os.path.abspath(dest)
if shareBase is DefaultShareBase:
shareBase = os.environ.get("HG_SHARE_BASE_DIR", None)
log.info("Reporting hg version in use")
cmd = ['hg', '-q', 'version']
run_cmd(cmd, cwd='.')
+ # New code path: if a share base directory is specified, use the
+ # robustcheckout extension/command for doing everything.
+ if shareBase and update_dest and (revision or branch):
+ robustcheckout_ext = get_hg_ext('robustcheckout.py')
+ cmd = [
+ 'hg',
+ '--config', 'extensions.robustcheckout=%s' % robustcheckout_ext,
+ 'robustcheckout', repo, dest,
+ '--sharebase', shareBase,
+ ]
+ if revision:
+ cmd.extend(['--revision', revision])
+ elif branch:
+ cmd.extend(['--branch', branch])
+
+ if autoPurge:
+ cmd.append('--purge')
+
+ # We only take the first mirror because that's all robustcheckout can
+ # take.
+ if mirrors:
+ cmd.extend(['--upstream', mirrors[0]])
+
+ try:
+ out = get_output(cmd, include_stderr=True)
+ for line in out.splitlines():
+ m = re.match('^updated to ([a-f0-9]{40})$', line)
+ if m:
+ return m.group(1)
+
+ raise HgUtilError('unable to find updated to revision')
+ except subprocess.CalledProcessError as e:
+ log.info('OUTPUT: %s' % e.output)
+ raise
+
if shareBase:
# Check that 'hg share' works
try:
log.info("Checking if share extension works")
output = get_hg_output(['help', 'share'], dont_log=True)
if 'no commands defined' in output:
# Share extension is enabled, but not functional
log.info("Disabling sharing since share extension doesn't seem to work (1)")