aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZach White <skullydazed@gmail.com>2021-08-28 19:37:55 -0700
committerGitHub <noreply@github.com>2021-08-29 12:37:55 +1000
commit566d59851634bf0ffb5b95dd85f65858b0905dc7 (patch)
tree7f632e9c4b08e231bad97e638d2635f9560b10b4
parentf155865804da332ac544e6a6bca0ca9035d3e818 (diff)
downloadqmk_firmware-566d59851634bf0ffb5b95dd85f65858b0905dc7.tar.gz
qmk_firmware-566d59851634bf0ffb5b95dd85f65858b0905dc7.zip
Add check for non-assignment code in rules.mk (#12108)
* Add check for non-assignment code in rules.mk * fix lint check * fix lint * fixup to reflect the final state of #8422 * fix lint
-rw-r--r--lib/python/qmk/cli/lint.py139
1 files changed, 98 insertions, 41 deletions
diff --git a/lib/python/qmk/cli/lint.py b/lib/python/qmk/cli/lint.py
index 02b31fbc4..008ec1393 100644
--- a/lib/python/qmk/cli/lint.py
+++ b/lib/python/qmk/cli/lint.py
@@ -1,72 +1,129 @@
1"""Command to look over a keyboard/keymap and check for common mistakes. 1"""Command to look over a keyboard/keymap and check for common mistakes.
2""" 2"""
3from pathlib import Path
4
3from milc import cli 5from milc import cli
4 6
5from qmk.decorators import automagic_keyboard, automagic_keymap 7from qmk.decorators import automagic_keyboard, automagic_keymap
6from qmk.info import info_json 8from qmk.info import info_json
7from qmk.keyboard import find_readme, keyboard_completer 9from qmk.keyboard import keyboard_completer, list_keyboards
8from qmk.keymap import locate_keymap 10from qmk.keymap import locate_keymap
9from qmk.path import is_keyboard, keyboard 11from qmk.path import is_keyboard, keyboard
10 12
11 13
14def keymap_check(kb, km):
15 """Perform the keymap level checks.
16 """
17 ok = True
18 keymap_path = locate_keymap(kb, km)
19
20 if not keymap_path:
21 ok = False
22 cli.log.error("%s: Can't find %s keymap.", kb, km)
23
24 return ok
25
26
27def rules_mk_assignment_only(keyboard_path):
28 """Check the keyboard-level rules.mk to ensure it only has assignments.
29 """
30 current_path = Path()
31 errors = []
32
33 for path_part in keyboard_path.parts:
34 current_path = current_path / path_part
35 rules_mk = current_path / 'rules.mk'
36
37 if rules_mk.exists():
38 continuation = None
39
40 for i, line in enumerate(rules_mk.open()):
41 line = line.strip()
42
43 if '#' in line:
44 line = line[:line.index('#')]
45
46 if continuation:
47 line = continuation + line
48 continuation = None
49
50 if line:
51 if line[-1] == '\\':
52 continuation = line[:-1]
53 continue
54
55 if line and '=' not in line:
56 errors.append(f'Non-assignment code on line +{i} {rules_mk}: {line}')
57
58 return errors
59
60
12@cli.argument('--strict', action='store_true', help='Treat warnings as errors.') 61@cli.argument('--strict', action='store_true', help='Treat warnings as errors.')
13@cli.argument('-kb', '--keyboard', completer=keyboard_completer, help='The keyboard to check.') 62@cli.argument('-kb', '--keyboard', completer=keyboard_completer, help='The keyboard to check.')
14@cli.argument('-km', '--keymap', help='The keymap to check.') 63@cli.argument('-km', '--keymap', help='The keymap to check.')
64@cli.argument('--all-kb', action='store_true', arg_only=True, help='Check all keyboards.')
15@cli.subcommand('Check keyboard and keymap for common mistakes.') 65@cli.subcommand('Check keyboard and keymap for common mistakes.')
16@automagic_keyboard 66@automagic_keyboard
17@automagic_keymap 67@automagic_keymap
18def lint(cli): 68def lint(cli):
19 """Check keyboard and keymap for common mistakes. 69 """Check keyboard and keymap for common mistakes.
20 """ 70 """
21 if not cli.config.lint.keyboard: 71 failed = []
22 cli.log.error('Missing required argument: --keyboard')
23 cli.print_help()
24 return False
25 72
26 if not is_keyboard(cli.config.lint.keyboard): 73 # Determine our keyboard list
27 cli.log.error('No such keyboard: %s', cli.config.lint.keyboard) 74 if cli.args.all_kb:
28 return False 75 if cli.args.keyboard:
76 cli.log.warning('Both --all-kb and --keyboard passed, --all-kb takes presidence.')
29 77
30 # Gather data about the keyboard. 78 keyboard_list = list_keyboards()
31 ok = True 79 elif not cli.config.lint.keyboard:
32 keyboard_path = keyboard(cli.config.lint.keyboard) 80 cli.log.error('Missing required arguments: --keyboard or --all-kb')
33 keyboard_info = info_json(cli.config.lint.keyboard) 81 cli.print_help()
34 readme_path = find_readme(cli.config.lint.keyboard) 82 return False
35 missing_readme_path = keyboard_path / 'readme.md' 83 else:
84 keyboard_list = cli.args.keyboard.split(',')
36 85
37 # Check for errors in the info.json 86 # Lint each keyboard
38 if keyboard_info['parse_errors']: 87 for kb in keyboard_list:
39 ok = False 88 if not is_keyboard(kb):
40 cli.log.error('Errors found when generating info.json.') 89 cli.log.error('No such keyboard: %s', kb)
90 continue
41 91
42 if cli.config.lint.strict and keyboard_info['parse_warnings']: 92 # Gather data about the keyboard.
43 ok = False 93 ok = True
44 cli.log.error('Warnings found when generating info.json (Strict mode enabled.)') 94 keyboard_path = keyboard(kb)
95 keyboard_info = info_json(kb)
45 96
46 # Check for a readme.md and warn if it doesn't exist 97 # Check for errors in the info.json
47 if not readme_path: 98 if keyboard_info['parse_errors']:
48 ok = False 99 ok = False
49 cli.log.error('Missing %s', missing_readme_path) 100 cli.log.error('%s: Errors found when generating info.json.', kb)
50 101
51 # Keymap specific checks 102 if cli.config.lint.strict and keyboard_info['parse_warnings']:
52 if cli.config.lint.keymap: 103 ok = False
53 keymap_path = locate_keymap(cli.config.lint.keyboard, cli.config.lint.keymap) 104 cli.log.error('%s: Warnings found when generating info.json (Strict mode enabled.)', kb)
54 105
55 if not keymap_path: 106 # Check the rules.mk file(s)
107 rules_mk_assignment_errors = rules_mk_assignment_only(keyboard_path)
108 if rules_mk_assignment_errors:
56 ok = False 109 ok = False
57 cli.log.error("Can't find %s keymap for %s keyboard.", cli.config.lint.keymap, cli.config.lint.keyboard) 110 cli.log.error('%s: Non-assignment code found in rules.mk. Move it to post_rules.mk instead.', kb)
58 else: 111 for assignment_error in rules_mk_assignment_errors:
59 keymap_readme = keymap_path.parent / 'readme.md' 112 cli.log.error(assignment_error)
60 if not keymap_readme.exists():
61 cli.log.warning('Missing %s', keymap_readme)
62 113
63 if cli.config.lint.strict: 114 # Keymap specific checks
64 ok = False 115 if cli.config.lint.keymap:
116 if not keymap_check(kb, cli.config.lint.keymap):
117 ok = False
118
119 # Report status
120 if not ok:
121 failed.append(kb)
65 122
66 # Check and report the overall status 123 # Check and report the overall status
67 if ok: 124 if failed:
68 cli.log.info('Lint check passed!') 125 cli.log.error('Lint check failed for: %s', ', '.join(failed))
69 return True 126 return False
70 127
71 cli.log.error('Lint check failed!') 128 cli.log.info('Lint check passed!')
72 return False 129 return True