зеркало из https://github.com/mozilla/gecko-dev.git
bug 855262 - add MozbuildObject.from_environment. r=glandium
This commit is contained in:
Родитель
1fdaad701e
Коммит
cfb4755f27
|
@ -4,6 +4,7 @@
|
|||
|
||||
from __future__ import print_function, unicode_literals
|
||||
|
||||
import json
|
||||
import logging
|
||||
import mozpack.path
|
||||
import multiprocessing
|
||||
|
@ -25,6 +26,36 @@ from .mozconfig import (
|
|||
MozconfigLoader,
|
||||
)
|
||||
|
||||
def ancestors(path):
|
||||
"""Emit the parent directories of a path."""
|
||||
while path:
|
||||
yield path
|
||||
newpath = os.path.dirname(path)
|
||||
if newpath == path:
|
||||
break
|
||||
path = newpath
|
||||
|
||||
def samepath(path1, path2):
|
||||
if hasattr(os.path, "samepath"):
|
||||
return os.path.samepath(path1, path2)
|
||||
return os.path.normpath(path1) == os.path.normpath(path2)
|
||||
|
||||
class BadEnvironmentException(Exception):
|
||||
"""Base class for errors raised when the build environment is not sane."""
|
||||
|
||||
|
||||
class BuildEnvironmentNotFoundException(BadEnvironmentException):
|
||||
"""Raised when we could not find a build environment."""
|
||||
|
||||
|
||||
class ObjdirMismatchException(BadEnvironmentException):
|
||||
"""Raised when the current dir is an objdir and doesn't match the mozconfig."""
|
||||
def __init__(self, objdir1, objdir2):
|
||||
self.objdir1 = objdir1
|
||||
self.objdir2 = objdir2
|
||||
|
||||
def __str__(self):
|
||||
return "Objdir mismatch: %s != %s" % (self.objdir1, self.objdir2)
|
||||
|
||||
class MozbuildObject(ProcessExecutionMixin):
|
||||
"""Base class providing basic functionality useful to many modules.
|
||||
|
@ -54,6 +85,90 @@ class MozbuildObject(ProcessExecutionMixin):
|
|||
self._config_guess_output = None
|
||||
self._config_environment = None
|
||||
|
||||
@classmethod
|
||||
def from_environment(cls):
|
||||
"""Create a MozbuildObject by detecting the proper one from the env.
|
||||
|
||||
This examines environment state like the current working directory and
|
||||
creates a MozbuildObject from the found source directory, mozconfig, etc.
|
||||
|
||||
The role of this function is to identify a topsrcdir, topobjdir, and
|
||||
mozconfig file.
|
||||
|
||||
If the current working directory is inside a known objdir, we always
|
||||
use the topsrcdir and mozconfig associated with that objdir. If no
|
||||
mozconfig is associated with that objdir, we fall back to looking for
|
||||
the mozconfig in the usual places.
|
||||
|
||||
If the current working directory is inside a known srcdir, we use that
|
||||
topsrcdir and look for mozconfigs using the default mechanism, which
|
||||
looks inside environment variables.
|
||||
|
||||
If the current Python interpreter is running from a virtualenv inside
|
||||
an objdir, we use that as our objdir.
|
||||
|
||||
If we're not inside a srcdir or objdir, an exception is raised.
|
||||
"""
|
||||
|
||||
topsrcdir = None
|
||||
topobjdir = None
|
||||
mozconfig = None
|
||||
|
||||
def load_mozinfo(path):
|
||||
info = json.load(open(path, 'rt'))
|
||||
topsrcdir = info.get('topsrcdir')
|
||||
topobjdir = os.path.dirname(path)
|
||||
mozconfig = info.get('mozconfig')
|
||||
return topsrcdir, topobjdir, mozconfig
|
||||
|
||||
for dir_path in ancestors(os.getcwd()):
|
||||
# If we find a mozinfo.json, we are in the objdir.
|
||||
mozinfo_path = os.path.join(dir_path, 'mozinfo.json')
|
||||
if os.path.isfile(mozinfo_path):
|
||||
topsrcdir, topobjdir, mozconfig = load_mozinfo(mozinfo_path)
|
||||
break
|
||||
|
||||
# We choose an arbitrary file as an indicator that this is a
|
||||
# srcdir. We go with ourself because why not!
|
||||
our_path = os.path.join(dir_path, 'python', 'mozbuild', 'mozbuild', 'base.py')
|
||||
if os.path.isfile(our_path):
|
||||
topsrcdir = dir_path
|
||||
break
|
||||
|
||||
if not topsrcdir:
|
||||
# See if we're running from a Python virtualenv that's inside an objdir.
|
||||
mozinfo_path = os.path.join(os.path.dirname(sys.prefix), "mozinfo.json")
|
||||
if os.path.isfile(mozinfo_path):
|
||||
topsrcdir, topobjdir, mozconfig = load_mozinfo(mozinfo_path)
|
||||
|
||||
# If we were successful, we're only guaranteed to find a topsrcdir. If
|
||||
# we couldn't find that, there's nothing we can do.
|
||||
if not topsrcdir:
|
||||
raise BuildEnvironmentNotFoundException(
|
||||
'Could not find Mozilla source tree or build environment.')
|
||||
|
||||
# Now we try to load the config for this environment. If mozconfig is
|
||||
# None, read_mozconfig() will attempt to find one in the existing
|
||||
# environment. If no mozconfig is present, the config will not have
|
||||
# much defined.
|
||||
loader = MozconfigLoader(topsrcdir)
|
||||
config = loader.read_mozconfig(mozconfig)
|
||||
|
||||
# If we're inside a objdir and the found mozconfig resolves to
|
||||
# another objdir, we abort. The reasoning here is that if you are
|
||||
# inside an objdir you probably want to perform actions on that objdir,
|
||||
# not another one.
|
||||
if topobjdir and config['topobjdir'] \
|
||||
and not samepath(topobjdir, config['topobjdir']):
|
||||
|
||||
raise ObjdirMismatchException(topobjdir, config['topobjdir'])
|
||||
|
||||
topobjdir = os.path.normpath(config['topobjdir'] or topobjdir)
|
||||
|
||||
# If we can't resolve topobjdir, oh well. The constructor will figure
|
||||
# it out via config.guess.
|
||||
return cls(topsrcdir, None, None, topobjdir=topobjdir)
|
||||
|
||||
@property
|
||||
def topobjdir(self):
|
||||
if self._topobjdir is None:
|
||||
|
|
|
@ -25,7 +25,7 @@ from mozbuild.backend.configenvironment import ConfigEnvironment
|
|||
|
||||
|
||||
curdir = os.path.dirname(__file__)
|
||||
topsrcdir = os.path.normpath(os.path.join(curdir, '..', '..', '..', '..'))
|
||||
topsrcdir = os.path.abspath(os.path.join(curdir, '..', '..', '..', '..'))
|
||||
log_manager = LoggingManager()
|
||||
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче