From a380937f1f36fba9d901e5eaa58119c509ed5f52 Mon Sep 17 00:00:00 2001 From: skullY Date: Tue, 21 Apr 2020 13:27:13 -0700 Subject: [PATCH] wip --- Makefile | 79 +++++++++++--------------- lib/python/qmk/cli/__init__.py | 1 + lib/python/qmk/cli/makehandler.py | 92 +++++++++++++++++++++++++++++++ 3 files changed, 124 insertions(+), 48 deletions(-) create mode 100755 lib/python/qmk/cli/makehandler.py diff --git a/Makefile b/Makefile index 9478c14f8c..5ebc22b1bb 100644 --- a/Makefile +++ b/Makefile @@ -557,55 +557,38 @@ endef # Let's match everything, we handle all the rule parsing ourselves .PHONY: % %: - # Check if we have the CMP tool installed - cmp $(ROOT_DIR)/Makefile $(ROOT_DIR)/Makefile >/dev/null 2>&1; if [ $$? -gt 0 ]; then printf "$(MSG_NO_CMP)"; exit 1; fi; - # Ensure that python3 is installed. This check can be removed after python is used in more places. - if ! python3 --version 1> /dev/null 2>&1; then printf "$(MSG_PYTHON_MISSING)"; fi - # Check if the submodules are dirty, and display a warning if they are -ifndef SKIP_GIT - if [ ! -e lib/chibios ]; then git submodule sync lib/chibios && git submodule update --depth 50 --init lib/chibios; fi - if [ ! -e lib/chibios-contrib ]; then git submodule sync lib/chibios-contrib && git submodule update --depth 50 --init lib/chibios-contrib; fi - if [ ! -e lib/ugfx ]; then git submodule sync lib/ugfx && git submodule update --depth 50 --init lib/ugfx; fi - if [ ! -e lib/lufa ]; then git submodule sync lib/lufa && git submodule update --depth 50 --init lib/lufa; fi - git submodule status --recursive 2>/dev/null | \ - while IFS= read -r x; do \ - case "$$x" in \ - \ *) ;; \ - *) printf "$(MSG_SUBMODULE_DIRTY)";break;; \ - esac \ - done -endif - rm -f $(ERROR_FILE) > /dev/null 2>&1 - $(eval $(call PARSE_RULE,$@)) - $(eval $(call SET_SILENT_MODE)) - # Run all the commands in the same shell, notice the + at the first line - # it has to be there to allow parallel execution of the submake - # This always tries to compile everything, even if error occurs in the middle - # But we return the error code at the end, to trigger travis failures - # The sort at this point is to remove duplicates - $(foreach COMMAND,$(sort $(COMMANDS)),$(RUN_COMMAND)) - if [ -f $(ERROR_FILE) ]; then printf "$(MSG_ERRORS)" & exit 1; fi; - $(foreach TEST,$(sort $(TESTS)),$(RUN_TEST)) - if [ -f $(ERROR_FILE) ]; then printf "$(MSG_ERRORS)" & exit 1; fi; +# # Check if we have the CMP tool installed +# cmp $(ROOT_DIR)/Makefile $(ROOT_DIR)/Makefile >/dev/null 2>&1; if [ $$? -gt 0 ]; then printf "$(MSG_NO_CMP)"; exit 1; fi; +# # Ensure that python3 is installed. This check can be removed after python is used in more places. +# if ! python3 --version 1> /dev/null 2>&1; then printf "$(MSG_PYTHON_MISSING)"; fi +# # Check if the submodules are dirty, and display a warning if they are +#ifndef SKIP_GIT +# if [ ! -e lib/chibios ]; then git submodule sync lib/chibios && git submodule update --depth 50 --init lib/chibios; fi +# if [ ! -e lib/chibios-contrib ]; then git submodule sync lib/chibios-contrib && git submodule update --depth 50 --init lib/chibios-contrib; fi +# if [ ! -e lib/ugfx ]; then git submodule sync lib/ugfx && git submodule update --depth 50 --init lib/ugfx; fi +# if [ ! -e lib/lufa ]; then git submodule sync lib/lufa && git submodule update --depth 50 --init lib/lufa; fi +# git submodule status --recursive 2>/dev/null | \ +# while IFS= read -r x; do \ +# case "$$x" in \ +# \ *) ;; \ +# *) printf "$(MSG_SUBMODULE_DIRTY)";break;; \ +# esac \ +# done +#endif +# rm -f $(ERROR_FILE) > /dev/null 2>&1 +# $(eval $(call PARSE_RULE,$@)) +# $(eval $(call SET_SILENT_MODE)) +# # Run all the commands in the same shell, notice the + at the first line +# # it has to be there to allow parallel execution of the submake +# # This always tries to compile everything, even if error occurs in the middle +# # But we return the error code at the end, to trigger travis failures +# # The sort at this point is to remove duplicates +# $(foreach COMMAND,$(sort $(COMMANDS)),$(RUN_COMMAND)) +# if [ -f $(ERROR_FILE) ]; then printf "$(MSG_ERRORS)" & exit 1; fi; +# $(foreach TEST,$(sort $(TESTS)),$(RUN_TEST)) +# if [ -f $(ERROR_FILE) ]; then printf "$(MSG_ERRORS)" & exit 1; fi; -# These no longer work because of the colon system - -# All should compile everything -# .PHONY: all -# all: all-keyboards test-all - -# Define some shortcuts, mostly for compatibility with the old syntax -# .PHONY: all-keyboards -# all-keyboards: all\:all\:all - -# .PHONY: all-keyboards-defaults -# all-keyboards-defaults: all\:default - -# .PHONY: test -# test: test-all - -# .PHONY: test-clean -# test-clean: test-all-clean + bin/qmk makehandler $@ lib/%: git submodule sync $? diff --git a/lib/python/qmk/cli/__init__.py b/lib/python/qmk/cli/__init__.py index 394a1353bc..46c3b4e5b6 100644 --- a/lib/python/qmk/cli/__init__.py +++ b/lib/python/qmk/cli/__init__.py @@ -17,6 +17,7 @@ from . import json from . import json2c from . import list from . import kle2json +from . import makehandler from . import new from . import pyformat from . import pytest diff --git a/lib/python/qmk/cli/makehandler.py b/lib/python/qmk/cli/makehandler.py new file mode 100755 index 0000000000..e0d9605f52 --- /dev/null +++ b/lib/python/qmk/cli/makehandler.py @@ -0,0 +1,92 @@ +"""Generate a make command from a `keyboard:keymap` pair. +""" +import os + +from milc import cli + +from qmk.path import is_keyboard + +def parse_rule(rule): + """Parses a QMK make rule into its compononent parts. + + Expects rule to be in the form `:[:]` + """ + rule = rule.split(':') + if len(rule) == 1: + return rule + ['all', ''] + + if len(rule) == 2: + return rule + [''] + + if len(rule) == 3: + return rule + + raise IndexError('rule %s has too many parts!' % rule) + + +@cli.argument('arguments', arg_only=True, nargs='+', help='Make arguments.') +@cli.subcommand('QMK Hello World.', hidden=True) +def makehandler(cli): + """Turn a `make keyboard:keymap` command into a full make command. + """ + environment = os.environ.copy() # FIXME: We should sanitize this + print('***', 'environment') + for key, value in environment.items(): + cli.log.info('%s=%s', key, value) + environment['COLOR'] = '1' if cli.config.general.color else '0' + environment['SILENT_MODE'] = '0' + environment['VERBOSE'] = '1' if cli.config.general.verbose else '0' + compile_targets = [] + + # Check submodules and warn if dirty + pass + + # Parse the command line (PARSE_RULE) + for argument in cli.args.arguments: + if "=" in argument: + key, value = argument.split('=', 1) + environment[key] = value + + else: + keyboard, keymap, command = parse_rule(argument) + keyboard_env = environment.copy() + + # Check the keyboard + if not (keyboard in ['all', 'test'] or is_keyboard(keyboard)): + cli.log.error('Invalid keyboard: %s', keyboard) + continue + + # Check the keymap + if not (keymap in ['all'] or True): # FIXME: Replace True with is_keymap(keyboard, keymap) + cli.log.error('Invalid keymap: %s', keymap) + continue + + # Add this compile target + keyboard_env['CURRENT_KB'] = keyboard_env['DEFAULT_FOLDER'] = keyboard_env['KEYBOARD_RULE'] = keyboard + compile_targets.append([keyboard, keymap, command, keyboard_env]) + + # Determine if we should turn on SILENT_MODE. + if 'SILENT' in environment: + for target in compile_targets: + target[3]['SILENT_MODE'] = environment['SILENT'] + elif len(compile_targets) > 1: + for target in compile_targets: + target[3]['SILENT_MODE'] = environment['SILENT'] + + # Iterate through our compile targets and generate make commands. + compiles_ok = True + for keyboard, keymap, command, environment in compile_targets: + print('***', repr(keyboard), repr(keymap), repr(command)) + for key, value in environment.items(): + cli.log.info('%s=%s', key, value) + + if not compiles_ok: + cli.log.error('{fg_red}Make finished with errors') + exit(1) + + # $(foreach TEST,$(sort $(TESTS)),$(RUN_TEST)) + tests_ok = False # FIXME: Set to true when all tests are true + + if not tests_ok: + # printf "$(MSG_ERRORS)" & exit 1 + pass