1
0
Fork 0
forked from forks/qmk_firmware

Perform stricter lint checks (#17348)

This commit is contained in:
Joel Challis 2022-06-14 14:54:46 +01:00 committed by GitHub
parent 15dab01e6a
commit f37de9a212
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 97 additions and 29 deletions

View file

@ -7,26 +7,43 @@ from milc import cli
from qmk.decorators import automagic_keyboard, automagic_keymap from qmk.decorators import automagic_keyboard, automagic_keymap
from qmk.info import info_json from qmk.info import info_json
from qmk.keyboard import keyboard_completer, list_keyboards from qmk.keyboard import keyboard_completer, list_keyboards
from qmk.keymap import locate_keymap from qmk.keymap import locate_keymap, list_keymaps
from qmk.path import is_keyboard, keyboard from qmk.path import is_keyboard, keyboard
from qmk.git import git_get_ignored_files
def keymap_check(kb, km): def _list_defaultish_keymaps(kb):
"""Perform the keymap level checks. """Return default like keymaps for a given keyboard
"""
defaultish = ['ansi', 'iso', 'via']
keymaps = set()
for x in list_keymaps(kb):
if x in defaultish or x.startswith('default'):
keymaps.add(x)
return keymaps
def _handle_json_errors(kb, info):
"""Convert any json errors into lint errors
""" """
ok = True ok = True
keymap_path = locate_keymap(kb, km) # Check for errors in the json
if info['parse_errors']:
if not keymap_path:
ok = False ok = False
cli.log.error("%s: Can't find %s keymap.", kb, km) cli.log.error(f'{kb}: Errors found when generating info.json.')
if cli.config.lint.strict and info['parse_warnings']:
ok = False
cli.log.error(f'{kb}: Warnings found when generating info.json (Strict mode enabled.)')
return ok return ok
def rules_mk_assignment_only(keyboard_path): def _rules_mk_assignment_only(kb):
"""Check the keyboard-level rules.mk to ensure it only has assignments. """Check the keyboard-level rules.mk to ensure it only has assignments.
""" """
keyboard_path = keyboard(kb)
current_path = Path() current_path = Path()
errors = [] errors = []
@ -58,10 +75,58 @@ def rules_mk_assignment_only(keyboard_path):
return errors return errors
def keymap_check(kb, km):
"""Perform the keymap level checks.
"""
ok = True
keymap_path = locate_keymap(kb, km)
if not keymap_path:
ok = False
cli.log.error("%s: Can't find %s keymap.", kb, km)
return ok
# Additional checks
invalid_files = git_get_ignored_files(keymap_path.parent)
for file in invalid_files:
cli.log.error(f'{kb}/{km}: The file "{file}" should not exist!')
ok = False
return ok
def keyboard_check(kb):
"""Perform the keyboard level checks.
"""
ok = True
kb_info = info_json(kb)
if not _handle_json_errors(kb, kb_info):
ok = False
# Additional checks
rules_mk_assignment_errors = _rules_mk_assignment_only(kb)
if rules_mk_assignment_errors:
ok = False
cli.log.error('%s: Non-assignment code found in rules.mk. Move it to post_rules.mk instead.', kb)
for assignment_error in rules_mk_assignment_errors:
cli.log.error(assignment_error)
invalid_files = git_get_ignored_files(f'keyboards/{kb}/')
for file in invalid_files:
if 'keymap' in file:
continue
cli.log.error(f'{kb}: The file "{file}" should not exist!')
ok = False
return ok
@cli.argument('--strict', action='store_true', help='Treat warnings as errors') @cli.argument('--strict', action='store_true', help='Treat warnings as errors')
@cli.argument('-kb', '--keyboard', completer=keyboard_completer, help='Comma separated list of keyboards to check') @cli.argument('-kb', '--keyboard', completer=keyboard_completer, help='Comma separated list of keyboards to check')
@cli.argument('-km', '--keymap', help='The keymap to check') @cli.argument('-km', '--keymap', help='The keymap to check')
@cli.argument('--all-kb', action='store_true', arg_only=True, help='Check all keyboards') @cli.argument('--all-kb', action='store_true', arg_only=True, help='Check all keyboards')
@cli.argument('--all-km', action='store_true', arg_only=True, help='Check all keymaps')
@cli.subcommand('Check keyboard and keymap for common mistakes.') @cli.subcommand('Check keyboard and keymap for common mistakes.')
@automagic_keyboard @automagic_keyboard
@automagic_keymap @automagic_keymap
@ -73,7 +138,7 @@ def lint(cli):
# Determine our keyboard list # Determine our keyboard list
if cli.args.all_kb: if cli.args.all_kb:
if cli.args.keyboard: if cli.args.keyboard:
cli.log.warning('Both --all-kb and --keyboard passed, --all-kb takes presidence.') cli.log.warning('Both --all-kb and --keyboard passed, --all-kb takes precedence.')
keyboard_list = list_keyboards() keyboard_list = list_keyboards()
elif not cli.config.lint.keyboard: elif not cli.config.lint.keyboard:
@ -89,31 +154,25 @@ def lint(cli):
cli.log.error('No such keyboard: %s', kb) cli.log.error('No such keyboard: %s', kb)
continue continue
# Gather data about the keyboard. # Determine keymaps to also check
if cli.args.all_km:
keymaps = list_keymaps(kb)
elif cli.config.lint.keymap:
keymaps = {cli.config.lint.keymap}
else:
keymaps = _list_defaultish_keymaps(kb)
# Ensure that at least a 'default' keymap always exists
keymaps.add('default')
ok = True ok = True
keyboard_path = keyboard(kb)
keyboard_info = info_json(kb)
# Check for errors in the info.json # keyboard level checks
if keyboard_info['parse_errors']: if not keyboard_check(kb):
ok = False ok = False
cli.log.error('%s: Errors found when generating info.json.', kb)
if cli.config.lint.strict and keyboard_info['parse_warnings']:
ok = False
cli.log.error('%s: Warnings found when generating info.json (Strict mode enabled.)', kb)
# Check the rules.mk file(s)
rules_mk_assignment_errors = rules_mk_assignment_only(keyboard_path)
if rules_mk_assignment_errors:
ok = False
cli.log.error('%s: Non-assignment code found in rules.mk. Move it to post_rules.mk instead.', kb)
for assignment_error in rules_mk_assignment_errors:
cli.log.error(assignment_error)
# Keymap specific checks # Keymap specific checks
if cli.config.lint.keymap: for keymap in keymaps:
if not keymap_check(kb, cli.config.lint.keymap): if not keymap_check(kb, keymap):
ok = False ok = False
# Report status # Report status

View file

@ -108,3 +108,12 @@ def git_check_deviation(active_branch):
cli.run(['git', 'fetch', 'upstream', active_branch]) cli.run(['git', 'fetch', 'upstream', active_branch])
deviations = cli.run(['git', '--no-pager', 'log', f'upstream/{active_branch}...{active_branch}']) deviations = cli.run(['git', '--no-pager', 'log', f'upstream/{active_branch}...{active_branch}'])
return bool(deviations.returncode) return bool(deviations.returncode)
def git_get_ignored_files(check_dir='.'):
"""Return a list of files that would be captured by the current .gitingore
"""
invalid = cli.run(['git', 'ls-files', '-c', '-o', '-i', '--exclude-standard', check_dir])
if invalid.returncode != 0:
return []
return invalid.stdout.strip().splitlines()