code: def check_message(message, **kwargs):
      
      if kwargs.pop("allow_empty", False):
          if not message or message.isspace():
              return []
  
      lines = re.split(r"\r\n|\r|\n", message)
      errors = _check_1st_line(lines[0], **kwargs)
      err, signature_lines = _check_bullets(lines, **kwargs)
      errors += err
      errors += _check_signatures(signature_lines, **kwargs)
  
      def _format(code, lineno, args):
          return "{0}: {1} {2}".format(lineno,
                                       code,
                                       _messages_codes[code].format(*args))
  
      return list(map(lambda x: _format(x[0], x[1], x[2:]),
                      sorted(errors, key=lambda x: x[0])))
docs: Check the message format.
  
      Rules:
  
      - the first line must start by a component name
      - and a short description (52 chars),
      - then bullet points are expected
      - and finally signatures.
  
      :param components: compontents, e.g. ``('auth', 'utils', 'misc')``
      :type components: `list`
      :param signatures: signatures, e.g. ``('Signed-off-by', 'Reviewed-by')``
      :type signatures: `list`
      :param alt_signatures: alternative signatures, e.g. ``('Tested-by',)``
      :type alt_signatures: `list`
      :param trusted: optional list of reviewers, e.g. ``('john.doe@foo.org',)``
      :type trusted: `list`
      :param max_length: optional maximum line length (by default: 72)
      :type max_length: int
      :param max_first_line: optional maximum first line length (by default: 50)
      :type max_first_line: int
      :param allow_empty: optional way to allow empty message (by default: False)
      :type allow_empty: bool
      :return: errors sorted by line number
      :rtype: `list`