-
-
Notifications
You must be signed in to change notification settings - Fork 39.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add check for non-assignment code in rules.mk
- Loading branch information
1 parent
7b8cdfc
commit 851fd80
Showing
1 changed file
with
102 additions
and
39 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,72 +1,135 @@ | ||
"""Command to look over a keyboard/keymap and check for common mistakes. | ||
""" | ||
from pathlib import Path | ||
|
||
from milc import cli | ||
|
||
from qmk.decorators import automagic_keyboard, automagic_keymap | ||
from qmk.info import info_json | ||
from qmk.keyboard import find_readme, keyboard_completer | ||
from qmk.keyboard import find_readme, keyboard_completer, list_keyboards | ||
from qmk.keymap import locate_keymap | ||
from qmk.path import is_keyboard, keyboard | ||
|
||
|
||
def rules_mk_assignment_only(keyboard_path): | ||
"""Check the keyboard-level rules.mk to ensure it only has assignments. | ||
""" | ||
current_path = Path() | ||
found_invalid = False | ||
|
||
for path_part in keyboard_path.parts: | ||
current_path = current_path / path_part | ||
rules_mk = current_path / 'rules.mk' | ||
|
||
if rules_mk.exists(): | ||
continuation = None | ||
|
||
for i, line in enumerate(rules_mk.open()): | ||
line = line.strip() | ||
|
||
if '#' in line: | ||
line = line[:line.index('#')] | ||
|
||
if continuation: | ||
line = continuation + line | ||
continuation = None | ||
|
||
if line: | ||
if line[-1] == '\\': | ||
continuation = line[:-1] | ||
continue | ||
|
||
if line and '=' not in line: | ||
cli.log.error('Non-assignment code: +%s %s: %s', i, rules_mk, line) | ||
found_invalid = True | ||
|
||
return not found_invalid | ||
|
||
|
||
@cli.argument('--strict', action='store_true', help='Treat warnings as errors.') | ||
@cli.argument('-kb', '--keyboard', completer=keyboard_completer, help='The keyboard 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.subcommand('Check keyboard and keymap for common mistakes.') | ||
@automagic_keyboard | ||
@automagic_keymap | ||
def lint(cli): | ||
"""Check keyboard and keymap for common mistakes. | ||
""" | ||
if not cli.config.lint.keyboard: | ||
cli.log.error('Missing required argument: --keyboard') | ||
failed = [] | ||
|
||
# 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.') | ||
|
||
keyboard_list = list_keyboards() | ||
elif not cli.config.lint.keyboard: | ||
cli.log.error('Missing required arguments: --keyboard or --all-kb') | ||
cli.print_help() | ||
return False | ||
else: | ||
keyboard_list = cli.args.keyboard.split(',') | ||
|
||
if not is_keyboard(cli.config.lint.keyboard): | ||
cli.log.error('No such keyboard: %s', cli.config.lint.keyboard) | ||
return False | ||
# Lint each keyboard | ||
for kb in keyboard_list: | ||
if not is_keyboard(kb): | ||
cli.log.error('No such keyboard: %s', kb) | ||
continue | ||
|
||
# Gather data about the keyboard. | ||
ok = True | ||
keyboard_path = keyboard(cli.config.lint.keyboard) | ||
keyboard_info = info_json(cli.config.lint.keyboard) | ||
readme_path = find_readme(cli.config.lint.keyboard) | ||
missing_readme_path = keyboard_path / 'readme.md' | ||
# Gather data about the keyboard. | ||
ok = True | ||
keyboard_path = keyboard(kb) | ||
keyboard_info = info_json(kb) | ||
info_path = keyboard_path / 'info.json' | ||
readme_path = keyboard_path / 'readme.md' | ||
|
||
# Check for errors in the info.json | ||
if keyboard_info['parse_errors']: | ||
ok = False | ||
cli.log.error('Errors found when generating info.json.') | ||
# 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) | ||
|
||
if cli.config.lint.strict and keyboard_info['parse_warnings']: | ||
ok = False | ||
cli.log.error('Warnings found when generating info.json (Strict mode enabled.)') | ||
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 for a readme.md and warn if it doesn't exist | ||
if not readme_path: | ||
ok = False | ||
cli.log.error('Missing %s', missing_readme_path) | ||
# Check for info.json and warn if it doesn't exist | ||
if not info_path.exists(): | ||
cli.log.warning('%s: Missing %s', kb, info_path) | ||
|
||
# Keymap specific checks | ||
if cli.config.lint.keymap: | ||
keymap_path = locate_keymap(cli.config.lint.keyboard, cli.config.lint.keymap) | ||
# Check for a readme.md and throw an error if it doesn't exist | ||
if not readme_path.exists(): | ||
ok = False | ||
cli.log.error('%s: Missing %s', kb, readme_path) | ||
|
||
if not keymap_path: | ||
# Check the rules.mk file(s) | ||
if not rules_mk_assignment_only(keyboard_path): | ||
ok = False | ||
cli.log.error("Can't find %s keymap for %s keyboard.", cli.config.lint.keymap, cli.config.lint.keyboard) | ||
else: | ||
keymap_readme = keymap_path.parent / 'readme.md' | ||
if not keymap_readme.exists(): | ||
cli.log.warning('Missing %s', keymap_readme) | ||
cli.log.error('%s: Non-assignment code found in rules.mk. Move it to processing.mk instead.', kb) | ||
|
||
if cli.config.lint.strict: | ||
ok = False | ||
# Keymap specific checks | ||
if cli.config.lint.keymap: | ||
keymap_path = locate_keymap(kb, cli.config.lint.keymap) | ||
|
||
if not keymap_path: | ||
ok = False | ||
cli.log.error("%s: Can't find %s keymap.", kb, cli.config.lint.keymap) | ||
else: | ||
keymap_readme = keymap_path.parent / 'readme.md' | ||
if not keymap_readme.exists(): | ||
cli.log.warning('%s: %s: Missing %s', kb, cli.config.lint.keymap, keymap_readme) | ||
|
||
if cli.config.lint.strict: | ||
ok = False | ||
|
||
if not ok: | ||
failed.append(kb) | ||
|
||
# Check and report the overall status | ||
if ok: | ||
cli.log.info('Lint check passed!') | ||
return True | ||
if failed: | ||
cli.log.error('Lint check failed for: %s', ', '.join(failed)) | ||
return False | ||
|
||
cli.log.info('Lint check passed!') | ||
return True | ||
|
||
cli.log.error('Lint check failed!') | ||
return False |