Skip to content

Commit

Permalink
Bug 1696251 - Pass MachCommandBase object as first argument for Mach …
Browse files Browse the repository at this point in the history
…Commands. r=mhentges,remote-protocol-reviewers,marionette-reviewers,webdriver-reviewers,perftest-reviewers

As an intermediate step to allow mach commands as standalone functions, the MachCommandBase
subclass instance that currently corresponds to self has to be made available as a separate
argument (named command_context).

Differential Revision: https://phabricator.services.mozilla.com/D109650
  • Loading branch information
alopezz committed May 17, 2021
1 parent 5992e82 commit 455d9a0
Show file tree
Hide file tree
Showing 62 changed files with 353 additions and 227 deletions.
2 changes: 1 addition & 1 deletion build/valgrind/mach_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ class MachCommands(MachCommandBase):
"--suppression multiple times to specify multiple suppression "
"files.",
)
def valgrind_test(self, suppressions):
def valgrind_test(self, command_context, suppressions):

from mozfile import TemporaryDirectory
from mozhttpd import MozHttpd
Expand Down
2 changes: 1 addition & 1 deletion devtools/shared/css/generated/mach_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ class MachCommands(MachCommandBase):
category="post-build",
description="Rebuild the devtool's static css properties database.",
)
def generate_css_db(self):
def generate_css_db(self, command_context):
"""Generate the static css properties database for devtools and write it to file."""

print("Re-generating the css properties database...")
Expand Down
4 changes: 2 additions & 2 deletions dom/bindings/mach_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class WebIDLProvider(MachCommandBase):
@CommandArgument(
"interface", nargs="+", help="Interface(s) whose examples to generate."
)
def webidl_example(self, interface):
def webidl_example(self, command_context, interface):
from mozwebidlcodegen import BuildSystemWebIDL

manager = self._spawn(BuildSystemWebIDL).manager
Expand All @@ -46,7 +46,7 @@ def webidl_example(self, interface):
parser=get_test_parser,
description="Run WebIDL tests (Interface Browser parser).",
)
def webidl_test(self, **kwargs):
def webidl_test(self, command_context, **kwargs):
sys.path.insert(0, os.path.join(self.topsrcdir, "other-licenses", "ply"))

# Ensure the topobjdir exists. On a Taskcluster test run there won't be
Expand Down
14 changes: 7 additions & 7 deletions js/src/devtools/rootAnalysis/mach_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ def setup_env_for_tools(self, env):
order="declaration",
description="Commands for running the static analysis for GC rooting hazards",
)
def hazards(self):
def hazards(self, command_context):
"""Commands related to performing the GC rooting hazard analysis"""
print("See `mach hazards --help` for a list of subcommands")

Expand All @@ -121,7 +121,7 @@ def hazards(self):
"bootstrap",
description="Install prerequisites for the hazard analysis",
)
def bootstrap(self, **kwargs):
def bootstrap(self, command_context, **kwargs):
orig_dir = os.getcwd()
os.chdir(self.ensure_dir_exists(self.tools_dir))
try:
Expand All @@ -142,7 +142,7 @@ def bootstrap(self, **kwargs):
metavar="FILENAME",
help="Build with the given mozconfig.",
)
def build_shell(self, **kwargs):
def build_shell(self, command_context, **kwargs):
"""Build a JS shell to use to run the rooting hazard analysis."""
# The JS shell requires some specific configuration settings to execute
# the hazard analysis code, and configuration is done via mozconfig.
Expand Down Expand Up @@ -215,7 +215,7 @@ def ensure_shell(self, objdir):
@CommandArgument(
"--work-dir", default=None, help="Directory for output and working files."
)
def gather_hazard_data(self, **kwargs):
def gather_hazard_data(self, command_context, **kwargs):
"""Gather analysis information by compiling the tree"""
application = kwargs["application"]
objdir = kwargs["haz_objdir"]
Expand Down Expand Up @@ -279,7 +279,7 @@ def gather_hazard_data(self, **kwargs):
default=os.environ.get("HAZ_OBJDIR"),
help="Write object files to this directory.",
)
def inner_compile(self, **kwargs):
def inner_compile(self, command_context, **kwargs):
"""Build a source tree and gather analysis information while running
under the influence of the analysis collection server."""

Expand Down Expand Up @@ -346,7 +346,7 @@ def inner_compile(self, **kwargs):
@CommandArgument(
"--work-dir", default=None, help="Directory for output and working files."
)
def analyze(self, application, shell_objdir, work_dir):
def analyze(self, command_context, application, shell_objdir, work_dir):
"""Analyzed gathered data for rooting hazards"""

shell = self.ensure_shell(shell_objdir)
Expand Down Expand Up @@ -374,7 +374,7 @@ def analyze(self, application, shell_objdir, work_dir):
default=None,
help="objdir containing the optimized JS shell for running the analysis.",
)
def self_test(self, shell_objdir):
def self_test(self, command_context, shell_objdir):
"""Analyzed gathered data for rooting hazards"""
shell = self.ensure_shell(shell_objdir)
args = [
Expand Down
6 changes: 3 additions & 3 deletions layout/tools/reftest/mach_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ class MachCommands(MachCommandBase):
description="Run reftests (layout and graphics correctness).",
parser=get_parser,
)
def run_reftest(self, **kwargs):
def run_reftest(self, command_context, **kwargs):
kwargs["suite"] = "reftest"
return self._run_reftest(**kwargs)

Expand All @@ -246,7 +246,7 @@ def run_reftest(self, **kwargs):
description="Run js/src/tests in the browser.",
parser=get_parser,
)
def run_jstestbrowser(self, **kwargs):
def run_jstestbrowser(self, command_context, **kwargs):
if "--enable-js-shell" not in self.mozconfig["configure_args"]:
raise Exception(
"jstestbrowser requires --enable-js-shell be specified in mozconfig."
Expand All @@ -263,7 +263,7 @@ def run_jstestbrowser(self, **kwargs):
description="Run crashtests (Check if crashes on a page).",
parser=get_parser,
)
def run_crashtest(self, **kwargs):
def run_crashtest(self, command_context, **kwargs):
kwargs["suite"] = "crashtest"
return self._run_reftest(**kwargs)

Expand Down
2 changes: 1 addition & 1 deletion layout/tools/reftest/mach_test_package_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ class ReftestCommands(MachCommandBase):
description="Run the reftest harness.",
parser=setup_argument_parser,
)
def reftest(self, **kwargs):
def reftest(self, command_context, **kwargs):
self._mach_context.activate_mozharness_venv()
kwargs["suite"] = "reftest"
return run_reftest(self._mach_context, **kwargs)
56 changes: 38 additions & 18 deletions mobile/android/mach_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ class MachCommands(MachCommandBase):
description="Run Android-specific commands.",
conditions=[conditions.is_android],
)
def android(self):
def android(self, command_context):
pass

@SubCommand(
Expand All @@ -67,8 +67,9 @@ def android(self):
See http://firefox-source-docs.mozilla.org/build/buildsystem/toolchains.html#firefox-for-android-with-gradle""", # NOQA: E501
)
@CommandArgument("args", nargs=argparse.REMAINDER)
def android_assemble_app(self, args):
def android_assemble_app(self, command_context, args):
ret = self.gradle(
command_context,
self.substs["GRADLE_ANDROID_APP_TASKS"] + ["-x", "lint"] + args,
verbose=True,
)
Expand All @@ -86,7 +87,7 @@ def android_assemble_app(self, args):
help="config files, " "like [/path/to/ClassName-classes.txt]+",
)
@CommandArgument("args", nargs=argparse.REMAINDER)
def android_generate_sdk_bindings(self, inputs, args):
def android_generate_sdk_bindings(self, command_context, inputs, args):
import itertools

def stem(input):
Expand All @@ -101,6 +102,7 @@ def stem(input):
)

ret = self.gradle(
command_context,
self.substs["GRADLE_ANDROID_GENERATE_SDK_BINDINGS_TASKS"]
+ [bindings_args]
+ args,
Expand All @@ -115,8 +117,9 @@ def stem(input):
"""Generate GeckoView JNI wrappers used when building GeckoView.""",
)
@CommandArgument("args", nargs=argparse.REMAINDER)
def android_generate_generated_jni_wrappers(self, args):
def android_generate_generated_jni_wrappers(self, command_context, args):
ret = self.gradle(
command_context,
self.substs["GRADLE_ANDROID_GENERATE_GENERATED_JNI_WRAPPERS_TASKS"] + args,
verbose=True,
)
Expand All @@ -129,7 +132,7 @@ def android_generate_generated_jni_wrappers(self, args):
"""Run Android api-lint.
REMOVED/DEPRECATED: Use 'mach lint --linter android-api-lint'.""",
)
def android_apilint_REMOVED(self):
def android_apilint_REMOVED(self, command_context):
print(LINT_DEPRECATION_MESSAGE)
return 1

Expand All @@ -139,7 +142,7 @@ def android_apilint_REMOVED(self):
"""Run Android test.
REMOVED/DEPRECATED: Use 'mach lint --linter android-test'.""",
)
def android_test_REMOVED(self):
def android_test_REMOVED(self, command_context):
print(LINT_DEPRECATION_MESSAGE)
return 1

Expand All @@ -149,7 +152,7 @@ def android_test_REMOVED(self):
"""Run Android lint.
REMOVED/DEPRECATED: Use 'mach lint --linter android-lint'.""",
)
def android_lint_REMOVED(self):
def android_lint_REMOVED(self, command_context):
print(LINT_DEPRECATION_MESSAGE)
return 1

Expand All @@ -159,7 +162,7 @@ def android_lint_REMOVED(self):
"""Run Android checkstyle.
REMOVED/DEPRECATED: Use 'mach lint --linter android-checkstyle'.""",
)
def android_checkstyle_REMOVED(self):
def android_checkstyle_REMOVED(self, command_context):
print(LINT_DEPRECATION_MESSAGE)
return 1

Expand All @@ -170,11 +173,12 @@ def android_checkstyle_REMOVED(self):
See http://firefox-source-docs.mozilla.org/build/buildsystem/toolchains.html#firefox-for-android-with-gradle""", # NOQA: E501
)
@CommandArgument("args", nargs=argparse.REMAINDER)
def android_gradle_dependencies(self, args):
def android_gradle_dependencies(self, command_context, args):
# We don't want to gate producing dependency archives on clean
# lint or checkstyle, particularly because toolchain versions
# can change the outputs for those processes.
self.gradle(
command_context,
self.substs["GRADLE_ANDROID_DEPENDENCIES_TASKS"] + ["--continue"] + args,
verbose=True,
)
Expand All @@ -188,17 +192,20 @@ def android_gradle_dependencies(self, args):
See http://firefox-source-docs.mozilla.org/build/buildsystem/toolchains.html#firefox-for-android-with-gradle""", # NOQA: E501
)
@CommandArgument("args", nargs=argparse.REMAINDER)
def android_archive_geckoview(self, args):
def android_archive_geckoview(self, command_context, args):
ret = self.gradle(
self.substs["GRADLE_ANDROID_ARCHIVE_GECKOVIEW_TASKS"] + args, verbose=True
command_context,
self.substs["GRADLE_ANDROID_ARCHIVE_GECKOVIEW_TASKS"] + args,
verbose=True,
)

return ret

@SubCommand("android", "build-geckoview_example", """Build geckoview_example """)
@CommandArgument("args", nargs=argparse.REMAINDER)
def android_build_geckoview_example(self, args):
def android_build_geckoview_example(self, command_context, args):
self.gradle(
command_context,
self.substs["GRADLE_ANDROID_BUILD_GECKOVIEW_EXAMPLE_TASKS"] + args,
verbose=True,
)
Expand All @@ -214,8 +221,9 @@ def android_build_geckoview_example(self, args):
"android", "install-geckoview_example", """Install geckoview_example """
)
@CommandArgument("args", nargs=argparse.REMAINDER)
def android_install_geckoview_example(self, args):
def android_install_geckoview_example(self, command_context, args):
self.gradle(
command_context,
self.substs["GRADLE_ANDROID_INSTALL_GECKOVIEW_EXAMPLE_TASKS"] + args,
verbose=True,
)
Expand Down Expand Up @@ -260,7 +268,13 @@ def android_install_geckoview_example(self, args):
help="Use the specified message for commits.",
)
def android_geckoview_docs(
self, archive, upload, upload_branch, javadoc_path, upload_message
self,
command_context,
archive,
upload,
upload_branch,
javadoc_path,
upload_message,
):

tasks = (
Expand All @@ -269,7 +283,7 @@ def android_geckoview_docs(
else self.substs["GRADLE_ANDROID_GECKOVIEW_DOCS_TASKS"]
)

ret = self.gradle(tasks, verbose=True)
ret = self.gradle(command_context, tasks, verbose=True)
if ret or not upload:
return ret

Expand Down Expand Up @@ -383,7 +397,7 @@ def android_geckoview_docs(
help="Verbose output for what commands the build is running.",
)
@CommandArgument("args", nargs=argparse.REMAINDER)
def gradle(self, args, verbose=False):
def gradle(self, command_context, args, verbose=False):
if not verbose:
# Avoid logging the command
self.log_manager.terminal_handler.setLevel(logging.CRITICAL)
Expand Down Expand Up @@ -442,7 +456,7 @@ def gradle(self, args, verbose=False):
)

@Command("gradle-install", category="devenv", conditions=[REMOVED])
def gradle_install_REMOVED(self):
def gradle_install_REMOVED(self, command_context):
pass


Expand Down Expand Up @@ -486,7 +500,13 @@ class AndroidEmulatorCommands(MachCommandBase):
"--verbose", action="store_true", help="Log informative status messages."
)
def emulator(
self, version, wait=False, force_update=False, gpu=None, verbose=False
self,
command_context,
version,
wait=False,
force_update=False,
gpu=None,
verbose=False,
):
from mozrunner.devices.android_device import AndroidEmulator

Expand Down
10 changes: 7 additions & 3 deletions python/mach/docs/commands.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,11 @@ The important decorators are as follows:
A method decorator that denotes that the method should be called when
the specified command is requested. The decorator takes a command name
as its first argument and a number of additional arguments to
configure the behavior of the command.
configure the behavior of the command. The decorated method must take a
``command_context`` argument as its first (after ``self``).
``command_context`` is a properly configured instance of a ``MozbuildObject``
subclass, meaning it can be used for accessing things like the current config
and running processes.

:py:func:`CommandArgument <mach.decorators.CommandArgument>`
A method decorator that defines an argument to the command. Its
Expand Down Expand Up @@ -51,7 +55,7 @@ Here is a complete example:
@Command('doit', help='Do ALL OF THE THINGS.')
@CommandArgument('--force', '-f', action='store_true',
help='Force doing it.')
def doit(self, force=False):
def doit(self, command_context, force=False):
# Do stuff here.
When the module is loaded, the decorators tell mach about all handlers.
Expand Down Expand Up @@ -101,7 +105,7 @@ Here is an example:
self.build_path = ...
@Command('run_tests', conditions=[build_available])
def run_tests(self):
def run_tests(self, command_context):
# Do stuff here.
It is important to make sure that any state needed by the condition is
Expand Down
Loading

0 comments on commit 455d9a0

Please sign in to comment.