diff options
Diffstat (limited to 'lib/python')
| -rw-r--r-- | lib/python/milc.py | 78 | ||||
| -rwxr-xr-x | lib/python/qmk/cli/doctor.py | 22 | ||||
| -rw-r--r-- | lib/python/qmk/questions.py | 7 | 
3 files changed, 76 insertions, 31 deletions
| diff --git a/lib/python/milc.py b/lib/python/milc.py index eb18984eb3..0cdd43dc89 100644 --- a/lib/python/milc.py +++ b/lib/python/milc.py @@ -18,9 +18,11 @@ import logging  import os  import re  import shlex +import subprocess  import sys  from decimal import Decimal  from pathlib import Path +from platform import platform  from tempfile import NamedTemporaryFile  from time import sleep @@ -94,29 +96,54 @@ def format_ansi(text):      return text + ansi_colors['style_reset_all'] -class ANSIFormatter(logging.Formatter): -    """A log formatter that inserts ANSI color. +class ANSIFormatterMixin(object): +    """A log formatter mixin that inserts ANSI color.      """      def format(self, record): -        msg = super(ANSIFormatter, self).format(record) +        msg = super(ANSIFormatterMixin, self).format(record)          return format_ansi(msg) -class ANSIEmojiLoglevelFormatter(ANSIFormatter): -    """A log formatter that makes the loglevel an emoji on UTF capable terminals. +class ANSIStrippingMixin(object): +    """A log formatter mixin that strips ANSI. +    """ +    def format(self, record): +        msg = super(ANSIStrippingMixin, self).format(record) +        record.levelname = ansi_escape.sub('', record.levelname) +        return ansi_escape.sub('', msg) + + +class EmojiLoglevelMixin(object): +    """A log formatter mixin that makes the loglevel an emoji on UTF capable terminals.      """      def format(self, record):          if UNICODE_SUPPORT:              record.levelname = EMOJI_LOGLEVELS[record.levelname].format(**ansi_colors) -        return super(ANSIEmojiLoglevelFormatter, self).format(record) +        return super(EmojiLoglevelMixin, self).format(record) -class ANSIStrippingFormatter(ANSIFormatter): -    """A log formatter that strips ANSI. +class ANSIFormatter(ANSIFormatterMixin, logging.Formatter): +    """A log formatter that colorizes output.      """ -    def format(self, record): -        msg = super(ANSIStrippingFormatter, self).format(record) -        return ansi_escape.sub('', msg) +    pass + + +class ANSIStrippingFormatter(ANSIStrippingMixin, ANSIFormatterMixin, logging.Formatter): +    """A log formatter that strips ANSI +    """ +    pass + + +class ANSIEmojiLoglevelFormatter(EmojiLoglevelMixin, ANSIFormatterMixin, logging.Formatter): +    """A log formatter that adds Emoji and ANSI +    """ +    pass + + +class ANSIStrippingEmojiLoglevelFormatter(ANSIStrippingMixin, EmojiLoglevelMixin, ANSIFormatterMixin, logging.Formatter): +    """A log formatter that adds Emoji and strips ANSI +    """ +    pass  class Configuration(object): @@ -288,11 +315,12 @@ class MILC(object):          self.config_file = None          self.default_arguments = {}          self.version = 'unknown' -        self.release_lock() +        self.platform = platform()          # Figure out our program name          self.prog_name = sys.argv[0][:-3] if sys.argv[0].endswith('.py') else sys.argv[0]          self.prog_name = self.prog_name.split('/')[-1] +        self.release_lock()          # Initialize all the things          self.read_config_file() @@ -315,6 +343,8 @@ class MILC(object):          strings.          If *args or **kwargs are passed they will be used to %-format the strings. + +        If `self.config.general.color` is False any ANSI escape sequences in the text will be stripped.          """          if args and kwargs:              raise RuntimeError('You can only specify *args or **kwargs, not both!') @@ -322,8 +352,27 @@ class MILC(object):          args = args or kwargs          text = format_ansi(text) +        if not self.config.general.color: +            text = ansi_escape.sub('', text) +          print(text % args) +    def run(self, command, *args, **kwargs): +        """Run a command with subprocess.run +        The *args and **kwargs arguments get passed directly to `subprocess.run`. +        """ +        if isinstance(command, str): +            raise TypeError('`command` must be a non-text sequence such as list or tuple.') + +        if 'windows' in self.platform.lower(): +            safecmd = map(shlex.quote, command) +            safecmd = ' '.join(safecmd) +            command = [os.environ['SHELL'], '-c', safecmd] + +        self.log.debug('Running command: %s', command) + +        return subprocess.run(command, *args, **kwargs) +      def initialize_argparse(self):          """Prepare to process arguments from sys.argv.          """ @@ -678,14 +727,13 @@ class MILC(object):              self.log_print_level = logging.DEBUG          self.log_file = self.config['general']['log_file'] or self.log_file -        self.log_file_format = self.config['general']['log_file_fmt']          self.log_file_format = ANSIStrippingFormatter(self.config['general']['log_file_fmt'], self.config['general']['datetime_fmt'])          self.log_format = self.config['general']['log_fmt']          if self.config.general.color: -            self.log_format = ANSIEmojiLoglevelFormatter(self.args.log_fmt, self.config.general.datetime_fmt) +            self.log_format = ANSIEmojiLoglevelFormatter(self.config.general.log_fmt, self.config.general.datetime_fmt)          else: -            self.log_format = ANSIStrippingFormatter(self.args.log_fmt, self.config.general.datetime_fmt) +            self.log_format = ANSIStrippingEmojiLoglevelFormatter(self.config.general.log_fmt, self.config.general.datetime_fmt)          if self.log_file:              self.log_file_handler = logging.FileHandler(self.log_file, self.log_file_mode) diff --git a/lib/python/qmk/cli/doctor.py b/lib/python/qmk/cli/doctor.py index 7fafd57575..9983865b31 100755 --- a/lib/python/qmk/cli/doctor.py +++ b/lib/python/qmk/cli/doctor.py @@ -156,24 +156,16 @@ def check_udev_rules():              _udev_rule("03EB", "2FF3"),  # ATmega16U4              _udev_rule("03EB", "2FF4"),  # ATmega32U4              _udev_rule("03EB", "2FF9"),  # AT90USB64 -            _udev_rule("03EB", "2FFB")   # AT90USB128 -        }, -        'kiibohd': { -            _udev_rule("1C11", "B007") +            _udev_rule("03EB", "2FFB")  # AT90USB128          }, +        'kiibohd': {_udev_rule("1C11", "B007")},          'stm32': {              _udev_rule("1EAF", "0003"),  # STM32duino -            _udev_rule("0483", "DF11")   # STM32 DFU -        }, -        'bootloadhid': { -            _udev_rule("16C0", "05DF") -        }, -        'usbasploader': { -            _udev_rule("16C0", "05DC") -        }, -        'massdrop': { -            _udev_rule("03EB", "6124") +            _udev_rule("0483", "DF11")  # STM32 DFU          }, +        'bootloadhid': {_udev_rule("16C0", "05DF")}, +        'usbasploader': {_udev_rule("16C0", "05DC")}, +        'massdrop': {_udev_rule("03EB", "6124")},          'caterina': {              # Spark Fun Electronics              _udev_rule("1B4F", "9203", 'ENV{ID_MM_DEVICE_IGNORE}="1"'),  # Pro Micro 3V3/8MHz @@ -190,7 +182,7 @@ def check_udev_rules():              _udev_rule("239A", "000E", 'ENV{ID_MM_DEVICE_IGNORE}="1"'),  # ItsyBitsy 32U4 5V/16MHz              # dog hunter AG              _udev_rule("2A03", "0036", 'ENV{ID_MM_DEVICE_IGNORE}="1"'),  # Leonardo -            _udev_rule("2A03", "0037", 'ENV{ID_MM_DEVICE_IGNORE}="1"')   # Micro +            _udev_rule("2A03", "0037", 'ENV{ID_MM_DEVICE_IGNORE}="1"')  # Micro          }      } diff --git a/lib/python/qmk/questions.py b/lib/python/qmk/questions.py index 27f43ac1e9..865c6bbdc5 100644 --- a/lib/python/qmk/questions.py +++ b/lib/python/qmk/questions.py @@ -1,7 +1,12 @@  """Functions to collect user input.  """ -from milc import cli, format_ansi +from milc import cli + +try: +    from milc import format_ansi +except ImportError: +    from milc.ansi import format_ansi  def yesno(prompt, *args, default=None, **kwargs): | 
