mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-04 13:07:52 +00:00
Bug 1399989 - Add python/mach to flake8 linter. r=gps
MozReview-Commit-ID: KKnBgYFwpfT --HG-- extra : rebase_source : 4e4b3453a91970366dba0073853ad3ab62738c81
This commit is contained in:
parent
57eb104b05
commit
d11ffd18db
@ -23,14 +23,14 @@ class BuiltinCommands(object):
|
||||
if not v.conditions or v.conditions[0].__name__ != 'REMOVED')
|
||||
|
||||
@Command('mach-commands', category='misc',
|
||||
description='List all mach commands.')
|
||||
description='List all mach commands.')
|
||||
def commands(self):
|
||||
print("\n".join(self.command_keys))
|
||||
|
||||
@Command('mach-debug-commands', category='misc',
|
||||
description='Show info about available mach commands.')
|
||||
description='Show info about available mach commands.')
|
||||
@CommandArgument('match', metavar='MATCH', default=None, nargs='?',
|
||||
help='Only display commands containing given substring.')
|
||||
help='Only display commands containing given substring.')
|
||||
def debug_commands(self, match=None):
|
||||
import inspect
|
||||
|
||||
@ -50,4 +50,3 @@ class BuiltinCommands(object):
|
||||
print('Class: %s' % cls.__name__)
|
||||
print('Method: %s' % handler.method)
|
||||
print('')
|
||||
|
||||
|
@ -274,7 +274,6 @@ class ConfigSettings(collections.Mapping):
|
||||
def __delattr__(self, k):
|
||||
self.__delitem__(k)
|
||||
|
||||
|
||||
def __init__(self):
|
||||
self._config = RawConfigParser()
|
||||
self._config.optionxform = str
|
||||
|
@ -7,7 +7,6 @@ from __future__ import absolute_import, unicode_literals
|
||||
import argparse
|
||||
import collections
|
||||
import inspect
|
||||
import os
|
||||
import types
|
||||
|
||||
from .base import MachError
|
||||
@ -185,7 +184,7 @@ def CommandProvider(cls):
|
||||
|
||||
if command.name not in seen_commands:
|
||||
raise MachError('Command referenced by sub-command does not '
|
||||
'exist: %s' % command.name)
|
||||
'exist: %s' % command.name)
|
||||
|
||||
if command.name not in Registrar.command_handlers:
|
||||
continue
|
||||
@ -235,6 +234,7 @@ class Command(object):
|
||||
|
||||
return func
|
||||
|
||||
|
||||
class SubCommand(object):
|
||||
"""Decorator for functions or methods that provide a sub-command.
|
||||
|
||||
@ -264,6 +264,7 @@ class SubCommand(object):
|
||||
|
||||
return func
|
||||
|
||||
|
||||
class CommandArgument(object):
|
||||
"""Decorator for additional arguments to mach subcommands.
|
||||
|
||||
@ -343,4 +344,3 @@ def SettingsProvider(cls):
|
||||
|
||||
Registrar.register_settings_provider(cls)
|
||||
return cls
|
||||
|
||||
|
@ -68,7 +68,7 @@ class CommandAction(argparse.Action):
|
||||
For more, read the docs in __call__.
|
||||
"""
|
||||
def __init__(self, option_strings, dest, required=True, default=None,
|
||||
registrar=None, context=None):
|
||||
registrar=None, context=None):
|
||||
# A proper API would have **kwargs here. However, since we are a little
|
||||
# hacky, we intentionally omit it as a way of detecting potentially
|
||||
# breaking changes with argparse's implementation.
|
||||
@ -76,7 +76,7 @@ class CommandAction(argparse.Action):
|
||||
# In a similar vein, default is passed in but is not needed, so we drop
|
||||
# it.
|
||||
argparse.Action.__init__(self, option_strings, dest, required=required,
|
||||
help=argparse.SUPPRESS, nargs=argparse.REMAINDER)
|
||||
help=argparse.SUPPRESS, nargs=argparse.REMAINDER)
|
||||
|
||||
self._mach_registrar = registrar
|
||||
self._context = context
|
||||
@ -276,7 +276,7 @@ class CommandAction(argparse.Action):
|
||||
|
||||
description = handler.description
|
||||
group.add_argument(command, help=description,
|
||||
action='store_true')
|
||||
action='store_true')
|
||||
|
||||
if disabled_commands and 'disabled' in r.categories:
|
||||
title, description, _priority = r.categories['disabled']
|
||||
@ -376,7 +376,7 @@ class CommandAction(argparse.Action):
|
||||
|
||||
for subcommand, subhandler in sorted(handler.subcommand_handlers.iteritems()):
|
||||
group.add_argument(subcommand, help=subhandler.description,
|
||||
action='store_true')
|
||||
action='store_true')
|
||||
|
||||
if handler.docstring:
|
||||
parser.description = format_docstring(handler.docstring)
|
||||
@ -413,7 +413,7 @@ class CommandAction(argparse.Action):
|
||||
def _suggest_command(self, command):
|
||||
# Make sure we don't suggest any deprecated commands.
|
||||
names = [h.name for h in self._mach_registrar.command_handlers.values()
|
||||
if h.cls.__name__ != 'DeprecatedCommands']
|
||||
if h.cls.__name__ != 'DeprecatedCommands']
|
||||
# We first try to look for a valid command that is very similar to the given command.
|
||||
suggested_commands = difflib.get_close_matches(command, names, cutoff=0.8)
|
||||
# If we find more than one matching command, or no command at all,
|
||||
|
@ -200,15 +200,17 @@ class LoggingManager(object):
|
||||
self.json_handlers.append(handler)
|
||||
|
||||
def add_terminal_logging(self, fh=sys.stdout, level=logging.INFO,
|
||||
write_interval=False, write_times=True):
|
||||
write_interval=False, write_times=True):
|
||||
"""Enable logging to the terminal."""
|
||||
|
||||
formatter = StructuredHumanFormatter(self.start_time,
|
||||
write_interval=write_interval, write_times=write_times)
|
||||
write_interval=write_interval,
|
||||
write_times=write_times)
|
||||
|
||||
if self.terminal:
|
||||
formatter = StructuredTerminalFormatter(self.start_time,
|
||||
write_interval=write_interval, write_times=write_times)
|
||||
write_interval=write_interval,
|
||||
write_times=write_times)
|
||||
formatter.set_terminal(self.terminal)
|
||||
|
||||
handler = logging.StreamHandler(stream=fh)
|
||||
|
@ -38,7 +38,6 @@ from .logging import LoggingManager
|
||||
from .registrar import Registrar
|
||||
|
||||
|
||||
|
||||
MACH_ERROR = r'''
|
||||
The error occurred in mach itself. This is likely a bug in mach itself or a
|
||||
fundamental problem with a loaded module.
|
||||
@ -103,6 +102,7 @@ to implement a mach command. Please fix the error, or uninstall the module from
|
||||
your system.
|
||||
'''.lstrip()
|
||||
|
||||
|
||||
class ArgumentParser(argparse.ArgumentParser):
|
||||
"""Custom implementation argument parser to make things look pretty."""
|
||||
|
||||
@ -361,7 +361,7 @@ To see more help for a specific command, run:
|
||||
print('mach interrupted by signal or user action. Stopping.')
|
||||
return 1
|
||||
|
||||
except Exception as e:
|
||||
except Exception:
|
||||
# _run swallows exceptions in invoked handlers and converts them to
|
||||
# a proper exit code. So, the only scenario where we should get an
|
||||
# exception here is if _run itself raises. If _run raises, that's a
|
||||
@ -393,8 +393,8 @@ To see more help for a specific command, run:
|
||||
self.load_settings(self.settings_paths)
|
||||
|
||||
context = CommandContext(cwd=self.cwd,
|
||||
settings=self.settings, log_manager=self.log_manager,
|
||||
commands=Registrar)
|
||||
settings=self.settings, log_manager=self.log_manager,
|
||||
commands=Registrar)
|
||||
|
||||
if self.populate_context_handler:
|
||||
self.populate_context_handler(context)
|
||||
@ -416,12 +416,14 @@ To see more help for a specific command, run:
|
||||
print(NO_COMMAND_ERROR)
|
||||
return 1
|
||||
except UnknownCommandError as e:
|
||||
suggestion_message = SUGGESTED_COMMANDS_MESSAGE % (e.verb, ', '.join(e.suggested_commands)) if e.suggested_commands else ''
|
||||
print(UNKNOWN_COMMAND_ERROR % (e.verb, e.command, suggestion_message))
|
||||
suggestion_message = SUGGESTED_COMMANDS_MESSAGE % (
|
||||
e.verb, ', '.join(e.suggested_commands)) if e.suggested_commands else ''
|
||||
print(UNKNOWN_COMMAND_ERROR %
|
||||
(e.verb, e.command, suggestion_message))
|
||||
return 1
|
||||
except UnrecognizedArgumentError as e:
|
||||
print(UNRECOGNIZED_ARGUMENT_ERROR % (e.command,
|
||||
' '.join(e.arguments)))
|
||||
' '.join(e.arguments)))
|
||||
return 1
|
||||
|
||||
# Add JSON logging to a file if requested.
|
||||
@ -442,7 +444,8 @@ To see more help for a specific command, run:
|
||||
# Always enable terminal logging. The log manager figures out if we are
|
||||
# actually in a TTY or are a pipe and does the right thing.
|
||||
self.log_manager.add_terminal_logging(level=log_level,
|
||||
write_interval=args.log_interval, write_times=write_times)
|
||||
write_interval=args.log_interval,
|
||||
write_times=write_times)
|
||||
|
||||
if args.settings_file:
|
||||
# Argument parsing has already happened, so settings that apply
|
||||
@ -456,7 +459,8 @@ To see more help for a specific command, run:
|
||||
|
||||
try:
|
||||
return Registrar._run_command_handler(handler, context=context,
|
||||
debug_command=args.debug_command, **vars(args.command_args))
|
||||
debug_command=args.debug_command,
|
||||
**vars(args.command_args))
|
||||
except KeyboardInterrupt as ki:
|
||||
raise ki
|
||||
except FailedCommandError as e:
|
||||
@ -477,7 +481,7 @@ To see more help for a specific command, run:
|
||||
if not len(stack):
|
||||
print(COMMAND_ERROR)
|
||||
self._print_exception(sys.stdout, exc_type, exc_value,
|
||||
traceback.extract_tb(exc_tb))
|
||||
traceback.extract_tb(exc_tb))
|
||||
return 1
|
||||
|
||||
# Split the frames into those from the module containing the
|
||||
@ -511,7 +515,7 @@ To see more help for a specific command, run:
|
||||
def log(self, level, action, params, format_str):
|
||||
"""Helper method to record a structured log event."""
|
||||
self.logger.log(level, format_str,
|
||||
extra={'action': action, 'params': params})
|
||||
extra={'action': action, 'params': params})
|
||||
|
||||
def _print_error_header(self, argv, fh):
|
||||
fh.write('Error running mach:\n\n')
|
||||
@ -542,6 +546,7 @@ To see more help for a specific command, run:
|
||||
paths = [paths]
|
||||
|
||||
valid_names = ('machrc', '.machrc')
|
||||
|
||||
def find_in_dir(base):
|
||||
if os.path.isfile(base):
|
||||
return base
|
||||
@ -560,38 +565,40 @@ To see more help for a specific command, run:
|
||||
"""Returns an argument parser for the command-line interface."""
|
||||
|
||||
parser = ArgumentParser(add_help=False,
|
||||
usage='%(prog)s [global arguments] command [command arguments]')
|
||||
usage='%(prog)s [global arguments] '
|
||||
'command [command arguments]')
|
||||
|
||||
# Order is important here as it dictates the order the auto-generated
|
||||
# help messages are printed.
|
||||
global_group = parser.add_argument_group('Global Arguments')
|
||||
|
||||
global_group.add_argument('-v', '--verbose', dest='verbose',
|
||||
action='store_true', default=False,
|
||||
help='Print verbose output.')
|
||||
action='store_true', default=False,
|
||||
help='Print verbose output.')
|
||||
global_group.add_argument('-l', '--log-file', dest='logfile',
|
||||
metavar='FILENAME', type=argparse.FileType('ab'),
|
||||
help='Filename to write log data to.')
|
||||
metavar='FILENAME', type=argparse.FileType('ab'),
|
||||
help='Filename to write log data to.')
|
||||
global_group.add_argument('--log-interval', dest='log_interval',
|
||||
action='store_true', default=False,
|
||||
help='Prefix log line with interval from last message rather '
|
||||
'than relative time. Note that this is NOT execution time '
|
||||
'if there are parallel operations.')
|
||||
action='store_true', default=False,
|
||||
help='Prefix log line with interval from last message rather '
|
||||
'than relative time. Note that this is NOT execution time '
|
||||
'if there are parallel operations.')
|
||||
suppress_log_by_default = False
|
||||
if 'INSIDE_EMACS' in os.environ:
|
||||
suppress_log_by_default = True
|
||||
global_group.add_argument('--log-no-times', dest='log_no_times',
|
||||
action='store_true', default=suppress_log_by_default,
|
||||
help='Do not prefix log lines with times. By default, mach will '
|
||||
'prefix each output line with the time since command start.')
|
||||
action='store_true', default=suppress_log_by_default,
|
||||
help='Do not prefix log lines with times. By default, '
|
||||
'mach will prefix each output line with the time since '
|
||||
'command start.')
|
||||
global_group.add_argument('-h', '--help', dest='help',
|
||||
action='store_true', default=False,
|
||||
help='Show this help message.')
|
||||
action='store_true', default=False,
|
||||
help='Show this help message.')
|
||||
global_group.add_argument('--debug-command', action='store_true',
|
||||
help='Start a Python debugger when command is dispatched.')
|
||||
help='Start a Python debugger when command is dispatched.')
|
||||
global_group.add_argument('--settings', dest='settings_file',
|
||||
metavar='FILENAME', default=None,
|
||||
help='Path to settings file.')
|
||||
metavar='FILENAME', default=None,
|
||||
help='Path to settings file.')
|
||||
|
||||
for args, kwargs in self.global_arguments:
|
||||
global_group.add_argument(*args, **kwargs)
|
||||
@ -599,6 +606,6 @@ To see more help for a specific command, run:
|
||||
# We need to be last because CommandAction swallows all remaining
|
||||
# arguments and argparse parses arguments in the order they were added.
|
||||
parser.add_argument('command', action=CommandAction,
|
||||
registrar=Registrar, context=context)
|
||||
registrar=Registrar, context=context)
|
||||
|
||||
return parser
|
||||
|
@ -51,5 +51,4 @@ class LoggingMixin(object):
|
||||
'User login: {username}')
|
||||
"""
|
||||
self._logger.log(level, format_str,
|
||||
extra={'action': action, 'params': params})
|
||||
|
||||
extra={'action': action, 'params': params})
|
||||
|
@ -41,9 +41,9 @@ class ProcessExecutionMixin(LoggingMixin):
|
||||
"""Mix-in that provides process execution functionality."""
|
||||
|
||||
def run_process(self, args=None, cwd=None, append_env=None,
|
||||
explicit_env=None, log_name=None, log_level=logging.INFO,
|
||||
line_handler=None, require_unix_environment=False,
|
||||
ensure_exit_code=0, ignore_children=False, pass_thru=False):
|
||||
explicit_env=None, log_name=None, log_level=logging.INFO,
|
||||
line_handler=None, require_unix_environment=False,
|
||||
ensure_exit_code=0, ignore_children=False, pass_thru=False):
|
||||
"""Runs a single process to completion.
|
||||
|
||||
Takes a list of arguments to run where the first item is the
|
||||
@ -131,8 +131,9 @@ class ProcessExecutionMixin(LoggingMixin):
|
||||
pass
|
||||
else:
|
||||
p = ProcessHandlerMixin(args, cwd=cwd, env=use_env,
|
||||
processOutputLine=[handleLine], universal_newlines=True,
|
||||
ignore_children=ignore_children)
|
||||
processOutputLine=[handleLine],
|
||||
universal_newlines=True,
|
||||
ignore_children=ignore_children)
|
||||
p.run()
|
||||
p.processOutput()
|
||||
status = p.wait()
|
||||
|
@ -29,11 +29,11 @@ class MachRegistrar(object):
|
||||
|
||||
if not handler.category:
|
||||
raise MachError('Cannot register a mach command without a '
|
||||
'category: %s' % name)
|
||||
'category: %s' % name)
|
||||
|
||||
if handler.category not in self.categories:
|
||||
raise MachError('Cannot register a command to an undefined '
|
||||
'category: %s -> %s' % (name, handler.category))
|
||||
'category: %s -> %s' % (name, handler.category))
|
||||
|
||||
self.command_handlers[name] = handler
|
||||
self.commands_by_category[handler.category].add(name)
|
||||
|
@ -72,4 +72,3 @@ class TerminalFooter(object):
|
||||
|
||||
def draw(self):
|
||||
raise Exception('draw() must be implemented.')
|
||||
|
||||
|
@ -9,10 +9,10 @@ import os
|
||||
import unittest
|
||||
|
||||
from mach.main import Mach
|
||||
from mach.base import CommandContext
|
||||
|
||||
here = os.path.abspath(os.path.dirname(__file__))
|
||||
|
||||
|
||||
class TestBase(unittest.TestCase):
|
||||
provider_dir = os.path.join(here, 'providers')
|
||||
|
||||
|
@ -9,14 +9,17 @@ from mach.decorators import (
|
||||
Command,
|
||||
)
|
||||
|
||||
|
||||
def is_foo(cls):
|
||||
"""Foo must be true"""
|
||||
return cls.foo
|
||||
|
||||
|
||||
def is_bar(cls):
|
||||
"""Bar must be true"""
|
||||
return cls.bar
|
||||
|
||||
|
||||
@CommandProvider
|
||||
class ConditionsProvider(object):
|
||||
foo = True
|
||||
@ -34,6 +37,7 @@ class ConditionsProvider(object):
|
||||
def run_foobar(self):
|
||||
pass
|
||||
|
||||
|
||||
@CommandProvider
|
||||
class ConditionsContextProvider(object):
|
||||
def __init__(self, context):
|
||||
|
@ -9,6 +9,7 @@ from mach.decorators import (
|
||||
Command,
|
||||
)
|
||||
|
||||
|
||||
@CommandProvider
|
||||
class ConditionsProvider(object):
|
||||
@Command('cmd_foo', category='testing', conditions=["invalid"])
|
||||
|
@ -4,8 +4,6 @@
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import time
|
||||
|
||||
from mach.decorators import (
|
||||
CommandArgument,
|
||||
CommandProvider,
|
||||
@ -26,4 +24,3 @@ class TestCommandProvider(object):
|
||||
@CommandArgument('--message', '-m', default='General Error')
|
||||
def throw_deep(self, message):
|
||||
throw2.throw_deep(message)
|
||||
|
||||
|
@ -6,8 +6,10 @@
|
||||
# exceptions that occur in mach command modules themselves and in the things
|
||||
# they call.
|
||||
|
||||
|
||||
def throw_deep(message):
|
||||
return throw_real(message)
|
||||
|
||||
|
||||
def throw_real(message):
|
||||
raise Exception(message)
|
||||
|
@ -23,6 +23,7 @@ def _populate_context(context, key=None):
|
||||
return False
|
||||
raise AttributeError(key)
|
||||
|
||||
|
||||
class TestConditions(TestBase):
|
||||
"""Tests for conditionally filtering commands."""
|
||||
|
||||
@ -30,7 +31,6 @@ class TestConditions(TestBase):
|
||||
return TestBase._run_mach(self, args, 'conditions.py',
|
||||
context_handler=context_handler)
|
||||
|
||||
|
||||
def test_conditions_pass(self):
|
||||
"""Test that a command which passes its conditions is runnable."""
|
||||
|
||||
@ -65,7 +65,7 @@ class TestConditions(TestBase):
|
||||
m = Mach(os.getcwd())
|
||||
m.define_category('testing', 'Mach unittest', 'Testing for mach core', 10)
|
||||
self.assertRaises(MachError, m.load_commands_from_file,
|
||||
os.path.join(self.provider_dir, 'conditions_invalid.py'))
|
||||
os.path.join(self.provider_dir, 'conditions_invalid.py'))
|
||||
|
||||
def test_help_message(self):
|
||||
"""Test that commands that are not runnable do not show up in help."""
|
||||
|
@ -40,6 +40,7 @@ CONFIG2 = r"""
|
||||
bar = value2
|
||||
"""
|
||||
|
||||
|
||||
@SettingsProvider
|
||||
class Provider1(object):
|
||||
config_settings = [
|
||||
|
@ -20,7 +20,7 @@ class TestErrorOutput(TestBase):
|
||||
|
||||
def test_command_error(self):
|
||||
result, stdout, stderr = self._run_mach(['throw', '--message',
|
||||
'Command Error'])
|
||||
'Command Error'])
|
||||
|
||||
self.assertEqual(result, 1)
|
||||
|
||||
@ -28,7 +28,7 @@ class TestErrorOutput(TestBase):
|
||||
|
||||
def test_invoked_error(self):
|
||||
result, stdout, stderr = self._run_mach(['throw_deep', '--message',
|
||||
'Deep stack'])
|
||||
'Deep stack'])
|
||||
|
||||
self.assertEqual(result, 1)
|
||||
|
||||
|
@ -40,7 +40,7 @@ class TestStructuredHumanFormatter(unittest.TestCase):
|
||||
value = 's\xe9curit\xe9'
|
||||
|
||||
logger.log(logging.INFO, 'Test: {utf}',
|
||||
extra={'action': 'action', 'params': {'utf': value}})
|
||||
extra={'action': 'action', 'params': {'utf': value}})
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
@ -36,4 +36,3 @@ setup(
|
||||
],
|
||||
tests_require=['mock'],
|
||||
)
|
||||
|
||||
|
@ -4,6 +4,7 @@ flake8:
|
||||
include:
|
||||
- config/mozunit.py
|
||||
- layout/tools/reftest
|
||||
- python/mach
|
||||
- python/mach_commands.py
|
||||
- python/mozlint
|
||||
- security/manager
|
||||
|
Loading…
x
Reference in New Issue
Block a user