addon-sdk/mach_commands.py
author Wes Kocher <wkocher@mozilla.com>
Thu, 09 Jul 2015 17:43:08 -0700
changeset 252149 fb0c6275d5c2b06d8467c9aa69ff2e50af16ecef
parent 250285 c8cedeb555cd8b3b084a1c3dad3a5e450e52f6e1
child 261065 e240f2db0b466d4bf15fa45654fcf9aa5a7e1db2
permissions -rw-r--r--
Backed out 5 changesets (bug 1180921) for build failures in BasePrincipal.cpp Backed out changeset d8c1a2e11a9a (bug 1180921) Backed out changeset f4dd8c53df5f (bug 1180921) Backed out changeset b272a0ebf5d8 (bug 1180921) Backed out changeset 8e86b6a7d201 (bug 1180921) Backed out changeset bbdebd7b8881 (bug 1180921)

# 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/.

# Integrates the xpcshell test runner with mach.

from __future__ import absolute_import

import os

import mozpack.path as mozpath

from mozbuild.base import (
    MachCommandBase,
    MozbuildObject,
)

from mach.decorators import (
    CommandArgument,
    CommandProvider,
    Command,
)

class JetpackRunner(MozbuildObject):
    """Run jetpack tests."""
    def run_tests(self, **kwargs):
        self._run_make(target='jetpack-tests')

@CommandProvider
class MachCommands(MachCommandBase):
    @Command('jetpack-test', category='testing',
        description='Run the jetpack test suite (Add-on SDK).')
    def run_jetpack_test(self, **params):
        # We should probably have a utility function to ensure the tree is
        # ready to run tests. Until then, we just create the state dir (in
        # case the tree wasn't built with mach).
        self._ensure_state_subdir_exists('.')

        jetpack = self._spawn(JetpackRunner)

        jetpack.run_tests(**params)

    @Command('generate-addon-sdk-moz-build', category='misc',
        description='Generates the moz.build file for the addon-sdk/ directory.')
    def run_addon_sdk_moz_build(self, **params):
        addon_sdk_dir = mozpath.join(self.topsrcdir, 'addon-sdk')
        js_src_dir = mozpath.join(addon_sdk_dir, 'source/lib')
        dirs_to_files = {}

        for path, dirs, files in os.walk(js_src_dir):
            js_files = [f for f in files if f.endswith(('.js', '.jsm', '.html'))]
            if not js_files:
                continue

            relative = mozpath.relpath(path, js_src_dir)
            dirs_to_files[relative] = js_files

        moz_build = """# AUTOMATICALLY GENERATED FROM mozbuild.template AND mach.  DO NOT EDIT.
# 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/.

%(moz-build-template)s
if CONFIG['MOZ_WIDGET_TOOLKIT'] != "gonk":
%(non-b2g-modules)s
%(always-on-modules)s"""

        non_b2g_paths = [
            'method/test',
            'sdk/ui',
            'sdk/ui/button',
            'sdk/ui/sidebar',
            'sdk/places',
            'sdk/places/host',
            'sdk/tabs',
            'sdk/panel',
            'sdk/frame',
            'sdk/test',
            'sdk/window',
            'sdk/windows',
            'sdk/deprecated',
        ]

        non_b2g_modules = []
        always_on_modules = []

        for d, files in sorted(dirs_to_files.items()):
            if d in non_b2g_paths:
                non_b2g_modules.append((d, files))
            else:
                always_on_modules.append((d, files))

        def list_to_js_modules(l, indent=''):
            js_modules = []
            for d, files in l:
                if d == '':
                    module_path = ''
                    dir_path = ''
                else:
                    # Ensure that we don't have things like:
                    #   EXTRA_JS_MODULES.commonjs.sdk.private-browsing
                    # which would be a Python syntax error.
                    path = d.split('/')
                    module_path = ''.join('.' + p if p.find('-') == -1 else "['%s']" % p for p in path)
                    dir_path = d + '/'
                filelist = ["'source/lib/%s%s'" % (dir_path, f)
                            for f in sorted(files, key=lambda x: x.lower())]
                js_modules.append("EXTRA_JS_MODULES.commonjs%s += [\n    %s,\n]\n"
                                  % (module_path, ',\n    '.join(filelist)))
            stringified = '\n'.join(js_modules)
            # This isn't the same thing as |js_modules|, since |js_modules| had
            # embedded newlines.
            lines = stringified.split('\n')
            # Indent lines while avoiding trailing whitespace.
            lines = [indent + line if line else line for line in lines]
            return '\n'.join(lines)

        moz_build_output = mozpath.join(addon_sdk_dir, 'moz.build')
        moz_build_template = mozpath.join(addon_sdk_dir, 'mozbuild.template')
        with open(moz_build_output, 'w') as f, open(moz_build_template, 'r') as t:
            substs = { 'moz-build-template': t.read(),
                       'non-b2g-modules': list_to_js_modules(non_b2g_modules,
                                                             indent='    '),
                       'always-on-modules': list_to_js_modules(always_on_modules) }
            f.write(moz_build % substs)