Bug 1505634 - Allow MOZ_ARTIFACT_REVISION to point to unknown mercurial changesets. r=nalexander
authorMike Hommey <mh+mozilla@glandium.org>
Fri, 09 Nov 2018 02:29:38 +0000
changeset 445361 b4b2dcb8de263b9ac64f9619e6acf24bbd4ceb18
parent 445243 63eb34f9b1712fe86b052727765db30fa068d6b7
child 445362 a85717115906b0d7803c3d6cf3d2950fdc865269
push id35015
push userdluca@mozilla.com
push dateFri, 09 Nov 2018 17:45:20 +0000
treeherdermozilla-central@2f1158e5e0ce [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnalexander
bugs1505634
milestone65.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1505634 - Allow MOZ_ARTIFACT_REVISION to point to unknown mercurial changesets. r=nalexander When using artifact builds, one can use the MOZ_ARTIFACT_REVISION environment variable to force download artifacts from the given revision. When the VCS is git, it expects the revision to be a git ref or commit sha1, which is resolved to a mercurial changeset via git-cinnabar. It can however be convenient to just point to a given mercurial revision directly, from, say, try, without pulling it first. This can actually be useful even when the VCS is mercurial. So if the given revision doesn't resolve to an existing git or hg commit, and it's a complete 40-character sha1, we assume it's a valid mercurial changeset. Differential Revision: https://phabricator.services.mozilla.com/D11266
python/mozbuild/mozbuild/artifacts.py
--- a/python/mozbuild/mozbuild/artifacts.py
+++ b/python/mozbuild/mozbuild/artifacts.py
@@ -1242,28 +1242,44 @@ class Artifacts(object):
                  'Tried {count} pushheads, no built artifacts found.')
         return 1
 
     def install_from_recent(self, distdir):
         hg_pushheads = self._find_pushheads()
         return self._install_from_hg_pushheads(hg_pushheads, distdir)
 
     def install_from_revset(self, revset, distdir):
-        if self._hg:
-            revision = subprocess.check_output([self._hg, 'log', '--template', '{node}\n',
-                                                '-r', revset], cwd=self._topsrcdir).strip()
-            if len(revision.split('\n')) != 1:
-                raise ValueError('hg revision specification must resolve to exactly one commit')
-        else:
-            revision = subprocess.check_output([self._git, 'rev-parse', revset], cwd=self._topsrcdir).strip()
-            revision = subprocess.check_output([self._git, 'cinnabar', 'git2hg', revision], cwd=self._topsrcdir).strip()
-            if len(revision.split('\n')) != 1:
-                raise ValueError('hg revision specification must resolve to exactly one commit')
-            if revision == "0" * 40:
-                raise ValueError('git revision specification must resolve to a commit known to hg')
+        revision = None
+        try:
+            if self._hg:
+                revision = subprocess.check_output([self._hg, 'log', '--template', '{node}\n',
+                                                  '-r', revset], cwd=self._topsrcdir).strip()
+            elif self._git:
+                revset = subprocess.check_output([
+                    self._git, 'rev-parse', '%s^{commit}' % revset],
+                    stderr=open(os.devnull, 'w'), cwd=self._topsrcdir).strip()
+            else:
+                # Fallback to the exception handling case from both hg and git
+                raise subprocess.CalledProcessError()
+        except subprocess.CalledProcessError:
+            # If the mercurial of git commands above failed, it means the given
+            # revset is not known locally to the VCS. But if the revset looks
+            # like a complete sha1, assume it is a mercurial sha1 that hasn't
+            # been pulled, and use that.
+            if re.match(r'^[A-Fa-f0-9]{40}$', revset):
+                revision = revset
+
+        if revision is None and self._git:
+            revision = subprocess.check_output(
+                [self._git, 'cinnabar', 'git2hg', revset], cwd=self._topsrcdir).strip()
+
+        if revision == "0" * 40 or revision is None:
+            raise ValueError('revision specification must resolve to a commit known to hg')
+        if len(revision.split('\n')) != 1:
+            raise ValueError('revision specification must resolve to exactly one commit')
 
         self.log(logging.INFO, 'artifact',
                  {'revset': revset,
                   'revision': revision},
                  'Will only accept artifacts from a pushhead at {revision} '
                  '(matched revset "{revset}").')
         # Include try in our search to allow pulling from a specific push.
         pushheads = [(list(CANDIDATE_TREES) + ['try'], revision)]