Bug 1377216 - Use configure-derived VCS info to find repository; r=glandium

For reasons I can't explain, Windows builds are failing intermittently
because they are unable to locate the `hg` binary when running
some SpiderMonkey test processes. These processes use
mozversioncontrol.get_repository_from_env() to locate the
current repository.

We now store VCS info in configure. This makes it available to anything
running in a build system context.

This commit teaches mozversioncontrol.get_repository_from_env()
to import the "buildconfig" module to locate VCS info. If the module
can be imported, it is the sole source of VCS info. Otherwise, we
fall back to the existing detection mechanisms.

This should get rid of the intermittent failure. If it doesn't,
it is still a step in the right direction because it will allow
build system processes to consistently use a well-defined VCS
binary.

MozReview-Commit-ID: DMxXheJLRqH

--HG--
extra : rebase_source : a9c599934c8c08da1fbb92a9105f5c7cba0867b3
This commit is contained in:
Gregory Szorc 2017-07-18 15:46:47 -07:00
parent 1e4d4f7e0f
commit 2e6b49383d

View File

@ -13,6 +13,9 @@ from distutils.version import LooseVersion
def get_tool_path(tool):
"""Obtain the path of `tool`."""
if os.path.isabs(tool) and os.path.exists(tool):
return tool
# We use subprocess in places, which expects a Win32 executable or
# batch script. On some versions of MozillaBuild, we have "hg.exe",
# "hg.bat," and "hg" (a Python script). "which" will happily return the
@ -83,8 +86,8 @@ class Repository(object):
class HgRepository(Repository):
'''An implementation of `Repository` for Mercurial repositories.'''
def __init__(self, path):
super(HgRepository, self).__init__(path, 'hg')
def __init__(self, path, hg='hg'):
super(HgRepository, self).__init__(path, tool=hg)
self._env[b'HGPLAIN'] = b'1'
def get_modified_files(self):
@ -112,8 +115,8 @@ class HgRepository(Repository):
class GitRepository(Repository):
'''An implementation of `Repository` for Git repositories.'''
def __init__(self, path):
super(GitRepository, self).__init__(path, 'git')
def __init__(self, path, git='git'):
super(GitRepository, self).__init__(path, tool=git)
def get_modified_files(self):
return self._run('diff', '--diff-filter=M', '--name-only').splitlines()
@ -148,8 +151,47 @@ def get_repository_object(path):
path)
class MissingVCSInfo(Exception):
"""Represents a general failure to resolve a VCS interface."""
class MissingConfigureInfo(MissingVCSInfo):
"""Represents error finding VCS info from configure data."""
def get_repository_from_env():
"""Obtain a repository object by looking at the environment."""
"""Obtain a repository object by looking at the environment.
If inside a build environment (denoted by presence of a ``buildconfig``
module), VCS info is obtained from it, as found via configure. This allows
us to respect what was passed into configure. Otherwise, we fall back to
scanning the filesystem.
"""
try:
import buildconfig
flavor = buildconfig.substs.get('VCS_CHECKOUT_TYPE')
# If in build mode, only use what configure found. That way we ensure
# that everything in the build system can be controlled via configure.
if not flavor:
raise MissingConfigureInfo('could not find VCS_CHECKOUT_TYPE '
'in build config; check configure '
'output and verify it could find a '
'VCS binary')
if flavor == 'hg':
return HgRepository(buildconfig.topsrcdir,
hg=buildconfig.substs['HG'])
elif flavor == 'git':
return GitRepository(buildconfig.topsrcdir,
git=buildconfig.subst['GIT'])
else:
raise MissingVCSInfo('unknown VCS_CHECKOUT_TYPE value: %s' % flavor)
except ImportError:
pass
def ancestors(path):
while path:
yield path
@ -163,5 +205,5 @@ def get_repository_from_env():
except InvalidRepoPath:
continue
raise Exception('Could not find Mercurial or Git checkout for %s' %
raise MissingVCSInfo('Could not find Mercurial or Git checkout for %s' %
os.getcwd())