summaryrefslogtreecommitdiff
path: root/lib/python
diff options
context:
space:
mode:
authorJoel Challis <git@zvecr.com>2022-06-14 14:54:46 +0100
committerGitHub <noreply@github.com>2022-06-14 14:54:46 +0100
commitf37de9a212e79e9c4c05c4298ba82ffe527d7132 (patch)
tree95f39b086111c97a759a14d7890035bae8d7ced9 /lib/python
parent15dab01e6ae68b47cf9df88ca935cbcc3f41d907 (diff)
downloadqmk_firmware-f37de9a212e79e9c4c05c4298ba82ffe527d7132.tar.gz
qmk_firmware-f37de9a212e79e9c4c05c4298ba82ffe527d7132.zip
Perform stricter lint checks (#17348)
Diffstat (limited to 'lib/python')
-rw-r--r--lib/python/qmk/cli/lint.py117
-rw-r--r--lib/python/qmk/git.py9
2 files changed, 97 insertions, 29 deletions
diff --git a/lib/python/qmk/cli/lint.py b/lib/python/qmk/cli/lint.py
index 96593ed69b..38b6457c43 100644
--- a/lib/python/qmk/cli/lint.py
+++ b/lib/python/qmk/cli/lint.py
@@ -7,26 +7,43 @@ from milc import cli
from qmk.decorators import automagic_keyboard, automagic_keymap
from qmk.info import info_json
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.git import git_get_ignored_files
-def keymap_check(kb, km):
- """Perform the keymap level checks.
+def _list_defaultish_keymaps(kb):
+ """Return default like keymaps for a given keyboard
"""
- ok = True
- keymap_path = locate_keymap(kb, km)
+ defaultish = ['ansi', 'iso', 'via']
- if not keymap_path:
+ 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
+ # Check for errors in the json
+ if info['parse_errors']:
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
-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.
"""
+ keyboard_path = keyboard(kb)
current_path = Path()
errors = []
@@ -58,10 +75,58 @@ def rules_mk_assignment_only(keyboard_path):
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('-kb', '--keyboard', completer=keyboard_completer, help='Comma separated list of keyboards 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-km', action='store_true', arg_only=True, help='Check all keymaps')
@cli.subcommand('Check keyboard and keymap for common mistakes.')
@automagic_keyboard
@automagic_keymap
@@ -73,7 +138,7 @@ def lint(cli):
# Determine our keyboard list
if cli.args.all_kb:
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()
elif not cli.config.lint.keyboard:
@@ -89,31 +154,25 @@ def lint(cli):
cli.log.error('No such keyboard: %s', kb)
continue
- # Gather data about the keyboard.
- ok = True
- keyboard_path = keyboard(kb)
- keyboard_info = info_json(kb)
-
- # Check for errors in the info.json
- if keyboard_info['parse_errors']:
- ok = False
- cli.log.error('%s: Errors found when generating info.json.', kb)
+ # 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')
- 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)
+ ok = True
- # Check the rules.mk file(s)
- rules_mk_assignment_errors = rules_mk_assignment_only(keyboard_path)
- if rules_mk_assignment_errors:
+ # keyboard level checks
+ if not keyboard_check(kb):
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
- if cli.config.lint.keymap:
- if not keymap_check(kb, cli.config.lint.keymap):
+ for keymap in keymaps:
+ if not keymap_check(kb, keymap):
ok = False
# Report status
diff --git a/lib/python/qmk/git.py b/lib/python/qmk/git.py
index beeb689144..f493628492 100644
--- a/lib/python/qmk/git.py
+++ b/lib/python/qmk/git.py
@@ -108,3 +108,12 @@ def git_check_deviation(active_branch):
cli.run(['git', 'fetch', 'upstream', active_branch])
deviations = cli.run(['git', '--no-pager', 'log', f'upstream/{active_branch}...{active_branch}'])
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()