mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 808357 - Part 1: Split mozconfig code into own Python module; r=glandium
--HG-- rename : python/mozbuild/mozbuild/base.py => python/mozbuild/mozbuild/mozconfig.py
This commit is contained in:
parent
aa43825f66
commit
f49dc5effc
@ -1,22 +1,20 @@
|
|||||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
# You can obtain one at http://mozilla.org/MPL/2.0/.
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import pymake.parser
|
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
import which
|
import which
|
||||||
|
|
||||||
from pymake.data import Makefile
|
|
||||||
|
|
||||||
from mach.mixin.logging import LoggingMixin
|
from mach.mixin.logging import LoggingMixin
|
||||||
from mach.mixin.process import ProcessExecutionMixin
|
from mach.mixin.process import ProcessExecutionMixin
|
||||||
|
|
||||||
from .config import BuildConfig
|
from .config import BuildConfig
|
||||||
|
from .mozconfig import MozconfigLoader
|
||||||
|
|
||||||
|
|
||||||
class MozbuildObject(ProcessExecutionMixin):
|
class MozbuildObject(ProcessExecutionMixin):
|
||||||
@ -41,20 +39,33 @@ class MozbuildObject(ProcessExecutionMixin):
|
|||||||
self.populate_logger()
|
self.populate_logger()
|
||||||
self.log_manager = log_manager
|
self.log_manager = log_manager
|
||||||
|
|
||||||
self._config_guess_output = None
|
|
||||||
self._make = None
|
self._make = None
|
||||||
self._topobjdir = topobjdir
|
self._topobjdir = topobjdir
|
||||||
|
self._mozconfig = None
|
||||||
|
self._config_guess_output = None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def topobjdir(self):
|
def topobjdir(self):
|
||||||
if self._topobjdir is None:
|
if self._topobjdir is None:
|
||||||
self._load_mozconfig()
|
if self.mozconfig['topobjdir'] is None:
|
||||||
|
self._topobjdir = 'obj-%s' % self._config_guess
|
||||||
if self._topobjdir is None:
|
else:
|
||||||
self._topobjdir = 'obj-%s' % self._config_guess
|
self._topobjdir = self.mozconfig['topobjdir']
|
||||||
|
|
||||||
return self._topobjdir
|
return self._topobjdir
|
||||||
|
|
||||||
|
@property
|
||||||
|
def mozconfig(self):
|
||||||
|
"""Returns information about the current mozconfig file.
|
||||||
|
|
||||||
|
This a dict as returned by MozconfigLoader.read_mozconfig()
|
||||||
|
"""
|
||||||
|
if self._mozconfig is None:
|
||||||
|
loader = MozconfigLoader(self.topsrcdir)
|
||||||
|
self._mozconfig = loader.read_mozconfig()
|
||||||
|
|
||||||
|
return self._mozconfig
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def distdir(self):
|
def distdir(self):
|
||||||
return os.path.join(self.topobjdir, 'dist')
|
return os.path.join(self.topobjdir, 'dist')
|
||||||
@ -67,63 +78,6 @@ class MozbuildObject(ProcessExecutionMixin):
|
|||||||
def statedir(self):
|
def statedir(self):
|
||||||
return os.path.join(self.topobjdir, '.mozbuild')
|
return os.path.join(self.topobjdir, '.mozbuild')
|
||||||
|
|
||||||
|
|
||||||
def _load_mozconfig(self, path=None):
|
|
||||||
# The mozconfig loader outputs a make file. We parse and load this make
|
|
||||||
# file with pymake and evaluate it in a context similar to client.mk.
|
|
||||||
|
|
||||||
loader = os.path.join(self.topsrcdir, 'build', 'autoconf',
|
|
||||||
'mozconfig2client-mk')
|
|
||||||
|
|
||||||
# os.environ from a library function is somewhat evil. But, mozconfig
|
|
||||||
# files are tightly coupled with the environment by definition. In the
|
|
||||||
# future, perhaps we'll have a more sanitized environment for mozconfig
|
|
||||||
# execution.
|
|
||||||
#
|
|
||||||
# The force of str is required because subprocess on Python <2.7.3
|
|
||||||
# does not like unicode in environment keys or values. At the time this
|
|
||||||
# was written, Mozilla shipped Python 2.7.2 with MozillaBuild.
|
|
||||||
env = dict(os.environ)
|
|
||||||
if path is not None:
|
|
||||||
env[str('MOZCONFIG')] = path
|
|
||||||
|
|
||||||
env[str('CONFIG_GUESS')] = self._config_guess
|
|
||||||
|
|
||||||
args = self._normalize_command([loader, self.topsrcdir], True)
|
|
||||||
|
|
||||||
output = subprocess.check_output(args, stderr=subprocess.PIPE,
|
|
||||||
cwd=self.topsrcdir, env=env)
|
|
||||||
|
|
||||||
# The output is make syntax. We parse this in a specialized make
|
|
||||||
# context.
|
|
||||||
statements = pymake.parser.parsestring(output, 'mozconfig')
|
|
||||||
|
|
||||||
makefile = Makefile(workdir=self.topsrcdir, env={
|
|
||||||
'TOPSRCDIR': self.topsrcdir,
|
|
||||||
'CONFIG_GUESS': self._config_guess})
|
|
||||||
|
|
||||||
statements.execute(makefile)
|
|
||||||
|
|
||||||
def get_value(name):
|
|
||||||
exp = makefile.variables.get(name)[2]
|
|
||||||
|
|
||||||
return exp.resolvestr(makefile, makefile.variables)
|
|
||||||
|
|
||||||
for name, flavor, source, value in makefile.variables:
|
|
||||||
# We only care about variables that came from the parsed mozconfig.
|
|
||||||
if source != pymake.data.Variables.SOURCE_MAKEFILE:
|
|
||||||
continue
|
|
||||||
|
|
||||||
# Ignore some pymake built-ins.
|
|
||||||
if name in ('.PYMAKE', 'MAKELEVEL', 'MAKEFLAGS'):
|
|
||||||
continue
|
|
||||||
|
|
||||||
if name == 'MOZ_OBJDIR':
|
|
||||||
self._topobjdir = get_value(name)
|
|
||||||
|
|
||||||
# If we want to extract other variables defined by mozconfig, here
|
|
||||||
# is where we'd do it.
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def _config_guess(self):
|
def _config_guess(self):
|
||||||
if self._config_guess_output is None:
|
if self._config_guess_output is None:
|
||||||
|
72
python/mozbuild/mozbuild/mozconfig.py
Normal file
72
python/mozbuild/mozbuild/mozconfig.py
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
import os
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
import pymake.parser
|
||||||
|
from pymake.data import Makefile
|
||||||
|
|
||||||
|
from mach.mixin.process import ProcessExecutionMixin
|
||||||
|
|
||||||
|
|
||||||
|
class MozconfigLoader(ProcessExecutionMixin):
|
||||||
|
"""Handles loading and parsing of mozconfig files."""
|
||||||
|
|
||||||
|
def __init__(self, topsrcdir):
|
||||||
|
self.topsrcdir = topsrcdir
|
||||||
|
|
||||||
|
@property
|
||||||
|
def _client_mk_loader_path(self):
|
||||||
|
return os.path.join(self.topsrcdir, 'build', 'autoconf',
|
||||||
|
'mozconfig2client-mk')
|
||||||
|
|
||||||
|
def read_mozconfig(self, path=None):
|
||||||
|
env = dict(os.environ)
|
||||||
|
if path is not None:
|
||||||
|
# Python < 2.7.3 doesn't like unicode strings in env keys.
|
||||||
|
env[b'MOZCONFIG'] = path
|
||||||
|
|
||||||
|
args = self._normalize_command([self._client_mk_loader_path,
|
||||||
|
self.topsrcdir], True)
|
||||||
|
|
||||||
|
output = subprocess.check_output(args, stderr=subprocess.PIPE,
|
||||||
|
cwd=self.topsrcdir, env=env)
|
||||||
|
|
||||||
|
# The output is make syntax. We parse this in a specialized make
|
||||||
|
# context.
|
||||||
|
statements = pymake.parser.parsestring(output, 'mozconfig')
|
||||||
|
|
||||||
|
makefile = Makefile(workdir=self.topsrcdir, env={
|
||||||
|
'TOPSRCDIR': self.topsrcdir})
|
||||||
|
|
||||||
|
statements.execute(makefile)
|
||||||
|
|
||||||
|
result = {
|
||||||
|
'topobjdir': None,
|
||||||
|
}
|
||||||
|
|
||||||
|
def get_value(name):
|
||||||
|
exp = makefile.variables.get(name)[2]
|
||||||
|
|
||||||
|
return exp.resolvestr(makefile, makefile.variables)
|
||||||
|
|
||||||
|
for name, flavor, source, value in makefile.variables:
|
||||||
|
# We only care about variables that came from the parsed mozconfig.
|
||||||
|
if source != pymake.data.Variables.SOURCE_MAKEFILE:
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Ignore some pymake built-ins.
|
||||||
|
if name in ('.PYMAKE', 'MAKELEVEL', 'MAKEFLAGS'):
|
||||||
|
continue
|
||||||
|
|
||||||
|
if name == 'MOZ_OBJDIR':
|
||||||
|
result['topobjdir'] = get_value(name)
|
||||||
|
|
||||||
|
# If we want to extract other variables defined by mozconfig, here
|
||||||
|
# is where we'd do it.
|
||||||
|
|
||||||
|
return result
|
@ -1,6 +1,6 @@
|
|||||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
# You can obtain one at http://mozilla.org/MPL/2.0/.
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
@ -26,27 +26,24 @@ class TestMozbuildObject(unittest.TestCase):
|
|||||||
def get_base(self):
|
def get_base(self):
|
||||||
return MozbuildObject(topsrcdir, None, log_manager)
|
return MozbuildObject(topsrcdir, None, log_manager)
|
||||||
|
|
||||||
def test_mozconfig_parsing(self):
|
|
||||||
with NamedTemporaryFile(mode='wt') as mozconfig:
|
|
||||||
mozconfig.write('mk_add_options MOZ_OBJDIR=@TOPSRCDIR@/some-objdir')
|
|
||||||
mozconfig.flush()
|
|
||||||
|
|
||||||
os.environ['MOZCONFIG'] = mozconfig.name
|
|
||||||
|
|
||||||
base = self.get_base()
|
|
||||||
base._load_mozconfig()
|
|
||||||
|
|
||||||
self.assertEqual(base.topobjdir, '%s/some-objdir' % topsrcdir)
|
|
||||||
|
|
||||||
del os.environ['MOZCONFIG']
|
|
||||||
|
|
||||||
def test_objdir_config_guess(self):
|
def test_objdir_config_guess(self):
|
||||||
base = self.get_base()
|
base = self.get_base()
|
||||||
|
|
||||||
with NamedTemporaryFile() as mozconfig:
|
with NamedTemporaryFile() as mozconfig:
|
||||||
os.environ['MOZCONFIG'] = mozconfig.name
|
os.environ[b'MOZCONFIG'] = mozconfig.name
|
||||||
|
|
||||||
self.assertIsNotNone(base.topobjdir)
|
self.assertIsNotNone(base.topobjdir)
|
||||||
self.assertEqual(len(base.topobjdir.split()), 1)
|
self.assertEqual(len(base.topobjdir.split()), 1)
|
||||||
|
self.assertTrue(base.topobjdir.endswith(base._config_guess))
|
||||||
|
|
||||||
|
del os.environ[b'MOZCONFIG']
|
||||||
|
|
||||||
|
def test_config_guess(self):
|
||||||
|
# It's difficult to test for exact values from the output of
|
||||||
|
# config.guess because they vary depending on platform.
|
||||||
|
base = self.get_base()
|
||||||
|
result = base._config_guess
|
||||||
|
|
||||||
|
self.assertIsNotNone(result)
|
||||||
|
self.assertGreater(len(result), 0)
|
||||||
|
|
||||||
del os.environ['MOZCONFIG']
|
|
||||||
|
32
python/mozbuild/mozbuild/test/test_mozconfig.py
Normal file
32
python/mozbuild/mozbuild/test/test_mozconfig.py
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
import os
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
from tempfile import NamedTemporaryFile
|
||||||
|
|
||||||
|
from mozbuild.mozconfig import MozconfigLoader
|
||||||
|
|
||||||
|
|
||||||
|
curdir = os.path.dirname(__file__)
|
||||||
|
topsrcdir = os.path.normpath(os.path.join(curdir, '..', '..', '..', '..'))
|
||||||
|
|
||||||
|
|
||||||
|
class TestMozconfigLoader(unittest.TestCase):
|
||||||
|
def get_loader(self):
|
||||||
|
return MozconfigLoader(topsrcdir)
|
||||||
|
|
||||||
|
def test_mozconfig_reading_moz_objdir(self):
|
||||||
|
with NamedTemporaryFile(mode='wt') as mozconfig:
|
||||||
|
mozconfig.write('mk_add_options MOZ_OBJDIR=@TOPSRCDIR@/some-objdir')
|
||||||
|
mozconfig.flush()
|
||||||
|
|
||||||
|
loader = self.get_loader()
|
||||||
|
result = loader.read_mozconfig(mozconfig.name)
|
||||||
|
|
||||||
|
self.assertEqual(result['topobjdir'], '%s/some-objdir' % topsrcdir)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user