Bug 808346 - Don't scan sys.path to discover mach commands; r=jhammel

All mach modules are now explicitly listed in the mach driver.

--HG--
rename : python/mozbuild/mach/commands/build.py => python/mozbuild/mozbuild/mach_commands.py
This commit is contained in:
Gregory Szorc 2012-11-06 17:00:19 -08:00
parent 576af377e9
commit 3d61e6990c
5 changed files with 53 additions and 87 deletions

2
mach
View File

@ -40,6 +40,7 @@ MACH_MODULES = [
'layout/tools/reftest/mach_commands.py', 'layout/tools/reftest/mach_commands.py',
'python/mozboot/mozboot/mach_commands.py', 'python/mozboot/mozboot/mach_commands.py',
'python/mozbuild/mozbuild/config.py', 'python/mozbuild/mozbuild/config.py',
'python/mozbuild/mozbuild/mach_commands.py',
'testing/mochitest/mach_commands.py', 'testing/mochitest/mach_commands.py',
'testing/xpcshell/mach_commands.py', 'testing/xpcshell/mach_commands.py',
] ]
@ -55,7 +56,6 @@ except ImportError:
# All of the code is in a module because EVERYTHING IS A LIBRARY. # All of the code is in a module because EVERYTHING IS A LIBRARY.
mach = mach.main.Mach(our_dir) mach = mach.main.Mach(our_dir)
mach.load_commands_from_sys_path()
for path in MACH_MODULES: for path in MACH_MODULES:
mach.load_commands_from_file(os.path.join(our_dir, path)) mach.load_commands_from_file(os.path.join(our_dir, path))

View File

@ -53,11 +53,7 @@ to the decorators are being used as arguments to
*mach.base* module for more. *mach.base* module for more.
The Python modules defining mach commands do not need to live inside the The Python modules defining mach commands do not need to live inside the
main mach source tree. If a path on *sys.path* contains a *mach/commands* main mach source tree.
directory, modules will be loaded automatically by mach and any classes
containing the decorators described above will be detected and loaded
automatically by mach. So, to add a new subcommand to mach, you just need
to ensure your Python module is present on *sys.path*.
Minimizing Code in Mach Minimizing Code in Mach
----------------------- -----------------------

View File

@ -145,28 +145,6 @@ To see more help for a specific command, run:
self.log_manager.register_structured_logger(self.logger) self.log_manager.register_structured_logger(self.logger)
def load_commands_from_sys_path(self):
"""Discover and load mach command modules from sys.path.
This iterates over all paths on sys.path. If the path contains a
"mach/commands" subdirectory, all .py files in that directory will be
loaded and examined for mach commands.
"""
# Create parent module otherwise Python complains when the parent is
# missing.
if b'mach.commands' not in sys.modules:
mod = imp.new_module(b'mach.commands')
sys.modules[b'mach.commands'] = mod
for path in sys.path:
# We only support importing .py files from directories.
commands_path = os.path.join(path, 'mach', 'commands')
if not os.path.isdir(commands_path):
continue
self.load_commands_from_directory(commands_path)
def load_commands_from_directory(self, path): def load_commands_from_directory(self, path):
"""Scan for mach commands from modules in a directory. """Scan for mach commands from modules in a directory.
@ -190,6 +168,12 @@ To see more help for a specific command, run:
chosen. chosen.
""" """
if module_name is None: if module_name is None:
# Ensure parent module is present otherwise we'll (likely) get
# an error due to unknown parent.
if b'mach.commands' not in sys.modules:
mod = imp.new_module(b'mach.commands')
sys.modules[b'mach.commands'] = mod
module_name = 'mach.commands.%s' % uuid.uuid1().get_hex() module_name = 'mach.commands.%s' % uuid.uuid1().get_hex()
imp.load_source(module_name, path) imp.load_source(module_name, path)

View File

@ -1,57 +0,0 @@
# 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 logging
import os
from mach.decorators import (
CommandProvider,
Command,
)
from mozbuild.base import MachCommandBase
@CommandProvider
class Build(MachCommandBase):
"""Interface to build the tree."""
@Command('build', help='Build the tree.')
def build(self):
# This code is only meant to be temporary until the more robust tree
# building code in bug 780329 lands.
from mozbuild.compilation.warnings import WarningsCollector
from mozbuild.compilation.warnings import WarningsDatabase
warnings_path = self._get_state_filename('warnings.json')
warnings_database = WarningsDatabase()
if os.path.exists(warnings_path):
warnings_database.load_from_file(warnings_path)
warnings_collector = WarningsCollector(database=warnings_database,
objdir=self.topobjdir)
def on_line(line):
try:
warning = warnings_collector.process_line(line)
if warning:
self.log(logging.INFO, 'compiler_warning', warning,
'Warning: {flag} in {filename}: {message}')
except:
# This will get logged in the more robust implementation.
pass
self.log(logging.INFO, 'build_output', {'line': line}, '{line}')
self._run_make(srcdir=True, filename='client.mk', line_handler=on_line,
log=False, print_directory=False)
self.log(logging.WARNING, 'warning_summary',
{'count': len(warnings_collector.database)},
'{count} compiler warnings present.')
warnings_database.save_to_file(warnings_path)

View File

@ -1,9 +1,10 @@
# 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 print_function, unicode_literals from __future__ import print_function, unicode_literals
import logging
import operator import operator
import os import os
@ -16,6 +17,48 @@ from mach.decorators import (
from mozbuild.base import MachCommandBase from mozbuild.base import MachCommandBase
@CommandProvider
class Build(MachCommandBase):
"""Interface to build the tree."""
@Command('build', help='Build the tree.')
def build(self):
# This code is only meant to be temporary until the more robust tree
# building code in bug 780329 lands.
from mozbuild.compilation.warnings import WarningsCollector
from mozbuild.compilation.warnings import WarningsDatabase
warnings_path = self._get_state_filename('warnings.json')
warnings_database = WarningsDatabase()
if os.path.exists(warnings_path):
warnings_database.load_from_file(warnings_path)
warnings_collector = WarningsCollector(database=warnings_database,
objdir=self.topobjdir)
def on_line(line):
try:
warning = warnings_collector.process_line(line)
if warning:
self.log(logging.INFO, 'compiler_warning', warning,
'Warning: {flag} in {filename}: {message}')
except:
# This will get logged in the more robust implementation.
pass
self.log(logging.INFO, 'build_output', {'line': line}, '{line}')
self._run_make(srcdir=True, filename='client.mk', line_handler=on_line,
log=False, print_directory=False)
self.log(logging.WARNING, 'warning_summary',
{'count': len(warnings_collector.database)},
'{count} compiler warnings present.')
warnings_database.save_to_file(warnings_path)
@CommandProvider @CommandProvider
class Warnings(MachCommandBase): class Warnings(MachCommandBase):
"""Provide commands for inspecting warnings.""" """Provide commands for inspecting warnings."""