bug 855262 - add MozbuildObject.from_environment. r=glandium

This commit is contained in:
Ted Mielczarek 2013-05-28 15:33:22 -04:00
Родитель 1fdaad701e
Коммит cfb4755f27
2 изменённых файлов: 116 добавлений и 1 удалений

Просмотреть файл

@ -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()