Bug 1388894 - Move loading of mach commands modules to registrar; r?ahal draft
authorGregory Szorc <gps@mozilla.com>
Wed, 09 Aug 2017 16:07:16 -0700
changeset 643666 ecafe806281ba5e24f0f9a8f920691cd7d8772b3
parent 643173 4c5fbf49376351679dcc49f4cff26c3c2e055ccc
child 643667 04e7fd60aa8dbd4729999586e731337cc617755d
child 643685 6c98f45f717e38ffb3f715d9a083f4377ac79ab1
push id73173
push userbmo:gps@mozilla.com
push dateThu, 10 Aug 2017 01:10:33 +0000
reviewersahal
bugs1388894
milestone57.0a1
Bug 1388894 - Move loading of mach commands modules to registrar; r?ahal This refactor will make it easier to lazy load modules. MozReview-Commit-ID: B3ktkVkaqYM
python/mach/mach/main.py
python/mach/mach/registrar.py
--- a/python/mach/mach/main.py
+++ b/python/mach/mach/main.py
@@ -5,36 +5,32 @@
 # This module provides functionality for the command-line build tool
 # (mach). It is packaged as a module because everything is a library.
 
 from __future__ import absolute_import, print_function, unicode_literals
 from collections import Iterable
 
 import argparse
 import codecs
-import imp
 import logging
 import os
 import sys
 import traceback
-import uuid
 
 from .base import (
     CommandContext,
     MachError,
     NoCommandError,
     UnknownCommandError,
     UnrecognizedArgumentError,
     FailedCommandError,
 )
 
 from .decorators import (
-    CommandArgument,
     CommandProvider,
-    Command,
 )
 
 from .config import ConfigSettings
 from .dispatcher import CommandAction
 from .logging import LoggingManager
 from .registrar import Registrar
 
 
@@ -249,26 +245,17 @@ To see more help for a specific command,
 
     def load_commands_from_file(self, path, module_name=None):
         """Scan for mach commands from a file.
 
         This takes a path to a file and loads it as a Python module under the
         module name specified. If no name is specified, a random one will be
         chosen.
         """
-        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()
-
-        imp.load_source(module_name, path)
+        Registrar.register_commands_file(path, module_name=module_name)
 
     def load_commands_from_entry_point(self, group='mach.providers'):
         """Scan installed packages for mach command provider entry points. An
         entry point is a function that returns a list of paths to files or
         directories containing command providers.
 
         This takes an optional group argument which specifies the entry point
         group to use. If not specified, it defaults to 'mach.providers'.
--- a/python/mach/mach/registrar.py
+++ b/python/mach/mach/registrar.py
@@ -1,14 +1,18 @@
 # 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 absolute_import, unicode_literals
 
+import imp
+import sys
+import uuid
+
 from .base import MachError
 
 INVALID_COMMAND_CONTEXT = r'''
 It looks like you tried to run a mach command from an invalid context. The %s
 command failed to meet the following conditions: %s
 
 Run |mach help| to show a list of all commands available to the current context.
 '''.lstrip()
@@ -19,16 +23,33 @@ class MachRegistrar(object):
 
     def __init__(self):
         self.command_handlers = {}
         self.commands_by_category = {}
         self.settings_providers = set()
         self.categories = {}
         self.require_conditions = False
 
+    def register_commands_file(self, path, module_name=None):
+        """Registers a file containing mach commands.
+
+        The file will eventually be imported. If not specified, the
+        module name will be ``mach.commands.<random>``.
+        """
+        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()
+
+        imp.load_source(module_name, path)
+
     def register_command_handler(self, handler):
         name = handler.name
 
         if not handler.category:
             raise MachError('Cannot register a mach command without a '
                 'category: %s' % name)
 
         if handler.category not in self.categories: