From a25dd58bc56b0c4010673723ac44eaff914979bb Mon Sep 17 00:00:00 2001 From: skullydazed Date: Mon, 15 Jul 2019 12:14:27 -0700 Subject: QMK CLI and JSON keymap support (#6176) * Script to generate keymap.c from JSON file. * Support for keymap.json * Add a warning about the keymap.c getting overwritten. * Fix keymap generating * Install the python deps * Flesh out more of the python environment * Remove defunct json2keymap * Style everything with yapf * Polish up python support * Hide json keymap.c into the .build dir * Polish up qmk-compile-json * Make milc work with positional arguments * Fix a couple small things * Fix some errors and make the CLI more understandable * Make the qmk wrapper more robust * Add basic QMK Doctor * Clean up docstrings and flesh them out as needed * remove unused compile_firmware() function --- bin/qmk | 97 ++++++++++++++++++++++++++++++++++++++++++++++++++++ bin/qmk-compile-json | 1 + bin/qmk-doctor | 1 + bin/qmk-hello | 1 + bin/qmk-json-keymap | 1 + 5 files changed, 101 insertions(+) create mode 100755 bin/qmk create mode 120000 bin/qmk-compile-json create mode 120000 bin/qmk-doctor create mode 120000 bin/qmk-hello create mode 120000 bin/qmk-json-keymap (limited to 'bin') diff --git a/bin/qmk b/bin/qmk new file mode 100755 index 0000000000..c34365bed4 --- /dev/null +++ b/bin/qmk @@ -0,0 +1,97 @@ +#!/usr/bin/env python3 +"""CLI wrapper for running QMK commands. +""" +import os +import subprocess +import sys +from glob import glob +from time import strftime +from importlib import import_module +from importlib.util import find_spec + +# Add the QMK python libs to our path +script_dir = os.path.dirname(os.path.realpath(__file__)) +qmk_dir = os.path.abspath(os.path.join(script_dir, '..')) +python_lib_dir = os.path.abspath(os.path.join(qmk_dir, 'lib', 'python')) +sys.path.append(python_lib_dir) + +# Change to the root of our checkout +os.environ['ORIG_CWD'] = os.getcwd() +os.chdir(qmk_dir) + +# Make sure our modules have been setup +with open('requirements.txt', 'r') as fd: + for line in fd.readlines(): + line = line.strip().replace('<', '=').replace('>', '=') + + if line[0] == '#': + continue + + if '#' in line: + line = line.split('#')[0] + + module = line.split('=')[0] if '=' in line else line + if not find_spec(module): + print('Your QMK build environment is not fully setup!\n') + print('Please run `./util/qmk_install.sh` to setup QMK.') + exit(255) + +# Figure out our version +command = ['git', 'describe', '--abbrev=6', '--dirty', '--always', '--tags'] +result = subprocess.run(command, text=True, capture_output=True) + +if result.returncode == 0: + os.environ['QMK_VERSION'] = 'QMK ' + result.stdout.strip() +else: + os.environ['QMK_VERSION'] = 'QMK ' + strftime('%Y-%m-%d-%H:%M:%S') + +# Setup the CLI +import milc +milc.EMOJI_LOGLEVELS['INFO'] = '{fg_blue}ψ{style_reset_all}' + +# If we were invoked as `qmk ` massage sys.argv into `qmk-`. +# This means we can't accept arguments to the qmk script itself. +script_name = os.path.basename(sys.argv[0]) +if script_name == 'qmk': + if len(sys.argv) == 1: + milc.cli.log.error('No subcommand specified!\n') + + if len(sys.argv) == 1 or sys.argv[1] in ['-h', '--help']: + milc.cli.echo('usage: qmk [...]') + milc.cli.echo('\nsubcommands:') + subcommands = glob(os.path.join(qmk_dir, 'bin', 'qmk-*')) + for subcommand in sorted(subcommands): + subcommand = os.path.basename(subcommand).split('-', 1)[1] + milc.cli.echo('\t%s', subcommand) + milc.cli.echo('\nqmk --help for more information') + exit(1) + + if sys.argv[1] in ['-V', '--version']: + milc.cli.echo(os.environ['QMK_VERSION']) + exit(0) + + sys.argv[0] = script_name = '-'.join((script_name, sys.argv[1])) + del sys.argv[1] + +# Look for which module to import +if script_name == 'qmk': + milc.cli.print_help() + exit(0) +elif not script_name.startswith('qmk-'): + milc.cli.log.error('Invalid symlink, must start with "qmk-": %s', script_name) +else: + subcommand = script_name.replace('-', '.').replace('_', '.').split('.') + subcommand.insert(1, 'cli') + subcommand = '.'.join(subcommand) + + try: + import_module(subcommand) + except ModuleNotFoundError as e: + if e.__class__.__name__ != subcommand: + raise + + milc.cli.log.error('Invalid subcommand! Could not import %s.', subcommand) + exit(1) + +if __name__ == '__main__': + milc.cli() diff --git a/bin/qmk-compile-json b/bin/qmk-compile-json new file mode 120000 index 0000000000..c92dce8a10 --- /dev/null +++ b/bin/qmk-compile-json @@ -0,0 +1 @@ +qmk \ No newline at end of file diff --git a/bin/qmk-doctor b/bin/qmk-doctor new file mode 120000 index 0000000000..c92dce8a10 --- /dev/null +++ b/bin/qmk-doctor @@ -0,0 +1 @@ +qmk \ No newline at end of file diff --git a/bin/qmk-hello b/bin/qmk-hello new file mode 120000 index 0000000000..c92dce8a10 --- /dev/null +++ b/bin/qmk-hello @@ -0,0 +1 @@ +qmk \ No newline at end of file diff --git a/bin/qmk-json-keymap b/bin/qmk-json-keymap new file mode 120000 index 0000000000..c92dce8a10 --- /dev/null +++ b/bin/qmk-json-keymap @@ -0,0 +1 @@ +qmk \ No newline at end of file -- cgit v1.2.3 From 3cb28bbe42a942275d3cbe530af6db4d72a37965 Mon Sep 17 00:00:00 2001 From: skullydazed Date: Wed, 7 Aug 2019 12:00:46 -0700 Subject: Use the older `universal_newlines` name instead of `text` (#6506) --- bin/qmk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'bin') diff --git a/bin/qmk b/bin/qmk index c34365bed4..dfd31e2006 100755 --- a/bin/qmk +++ b/bin/qmk @@ -38,7 +38,7 @@ with open('requirements.txt', 'r') as fd: # Figure out our version command = ['git', 'describe', '--abbrev=6', '--dirty', '--always', '--tags'] -result = subprocess.run(command, text=True, capture_output=True) +result = subprocess.run(command, universal_newlines=True, capture_output=True) if result.returncode == 0: os.environ['QMK_VERSION'] = 'QMK ' + result.stdout.strip() -- cgit v1.2.3 From f22c5c17b6fe069bec1241262a1c27eb89d3d3af Mon Sep 17 00:00:00 2001 From: skullydazed Date: Sun, 25 Aug 2019 11:58:24 -0700 Subject: Refactor `qmk compile-json` to `qmk compile` (#6592) --- bin/qmk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'bin') diff --git a/bin/qmk b/bin/qmk index dfd31e2006..d4b584b10e 100755 --- a/bin/qmk +++ b/bin/qmk @@ -38,7 +38,7 @@ with open('requirements.txt', 'r') as fd: # Figure out our version command = ['git', 'describe', '--abbrev=6', '--dirty', '--always', '--tags'] -result = subprocess.run(command, universal_newlines=True, capture_output=True) +result = subprocess.run(command, universal_newlines=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) if result.returncode == 0: os.environ['QMK_VERSION'] = 'QMK ' + result.stdout.strip() -- cgit v1.2.3 From c27aa60c50c7ed7cb3e511c8a9def118541813e7 Mon Sep 17 00:00:00 2001 From: fauxpark Date: Sat, 31 Aug 2019 03:23:36 +1000 Subject: =?UTF-8?q?Make=20the=20CLI=20=CE=A8=20capital=20(#6637)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bin/qmk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'bin') diff --git a/bin/qmk b/bin/qmk index d4b584b10e..3c00a675eb 100755 --- a/bin/qmk +++ b/bin/qmk @@ -47,7 +47,7 @@ else: # Setup the CLI import milc -milc.EMOJI_LOGLEVELS['INFO'] = '{fg_blue}ψ{style_reset_all}' +milc.EMOJI_LOGLEVELS['INFO'] = '{fg_blue}Ψ{style_reset_all}' # If we were invoked as `qmk ` massage sys.argv into `qmk-`. # This means we can't accept arguments to the qmk script itself. -- cgit v1.2.3 From 5b7a5b2a7629fbb667d23a55836dce3c6c46a203 Mon Sep 17 00:00:00 2001 From: skullY Date: Wed, 21 Aug 2019 23:40:24 -0700 Subject: Setup a python test framework --- bin/qmk | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'bin') diff --git a/bin/qmk b/bin/qmk index 3c00a675eb..1aa16e17dc 100755 --- a/bin/qmk +++ b/bin/qmk @@ -94,4 +94,10 @@ else: exit(1) if __name__ == '__main__': - milc.cli() + return_code = milc.cli() + if return_code is False: + exit(1) + elif return_code is not True and isinstance(return_code, int) and return_code < 256: + exit(return_code) + else: + exit(0) -- cgit v1.2.3 From d569f0877155efc752994f8a21f5cf001f9d6ae6 Mon Sep 17 00:00:00 2001 From: skullydazed Date: Sun, 22 Sep 2019 13:25:33 -0700 Subject: Configuration system for CLI (#6708) * Rework how bin/qmk handles subcommands * qmk config wip * Code to show all configs * Fully working `qmk config` command * Mark some CLI arguments so they don't pollute the config file * Fleshed out config support, nicer subcommand support * sync with installable cli * pyformat * Add a test for subcommand_modules * Documentation for the `qmk config` command * split config_token on space so qmk config is more predictable * Rework how subcommands are imported * Document `arg_only` * Document deleting from CLI * Document how multiple operations work * Add cli config to the doc index * Add tests for the cli commands * Make running the tests more reliable * Be more selective about building all default keymaps * Update new-keymap to fit the new subcommand style * Add documentation about writing CLI scripts * Document new-keyboard * Update docs/cli_configuration.md Co-Authored-By: noroadsleft <18669334+noroadsleft@users.noreply.github.com> * Update docs/cli_development.md Co-Authored-By: noroadsleft <18669334+noroadsleft@users.noreply.github.com> * Update docs/cli_development.md Co-Authored-By: noroadsleft <18669334+noroadsleft@users.noreply.github.com> * Update docs/cli_development.md Co-Authored-By: noroadsleft <18669334+noroadsleft@users.noreply.github.com> * Address yan's comments. * Apply suggestions from code review suggestions from @noahfrederick Co-Authored-By: Noah Frederick * Apply suggestions from code review Co-Authored-By: Noah Frederick * Remove pip3 from the test runner --- bin/qmk | 92 ++++++++++++++++++++-------------------------------- bin/qmk-compile-json | 1 - bin/qmk-doctor | 1 - bin/qmk-hello | 1 - bin/qmk-json-keymap | 1 - 5 files changed, 36 insertions(+), 60 deletions(-) delete mode 120000 bin/qmk-compile-json delete mode 120000 bin/qmk-doctor delete mode 120000 bin/qmk-hello delete mode 120000 bin/qmk-json-keymap (limited to 'bin') diff --git a/bin/qmk b/bin/qmk index 1aa16e17dc..876473fa43 100755 --- a/bin/qmk +++ b/bin/qmk @@ -4,10 +4,8 @@ import os import subprocess import sys -from glob import glob -from time import strftime -from importlib import import_module from importlib.util import find_spec +from time import strftime # Add the QMK python libs to our path script_dir = os.path.dirname(os.path.realpath(__file__)) @@ -15,12 +13,8 @@ qmk_dir = os.path.abspath(os.path.join(script_dir, '..')) python_lib_dir = os.path.abspath(os.path.join(qmk_dir, 'lib', 'python')) sys.path.append(python_lib_dir) -# Change to the root of our checkout -os.environ['ORIG_CWD'] = os.getcwd() -os.chdir(qmk_dir) - # Make sure our modules have been setup -with open('requirements.txt', 'r') as fd: +with open(os.path.join(qmk_dir, 'requirements.txt'), 'r') as fd: for line in fd.readlines(): line = line.strip().replace('<', '=').replace('>', '=') @@ -32,72 +26,58 @@ with open('requirements.txt', 'r') as fd: module = line.split('=')[0] if '=' in line else line if not find_spec(module): - print('Your QMK build environment is not fully setup!\n') - print('Please run `./util/qmk_install.sh` to setup QMK.') + print('Could not find module %s!', module) + print('Please run `pip3 install -r requirements.txt` to install the python dependencies.') exit(255) # Figure out our version +# TODO(skullydazed/anyone): Find a method that doesn't involve git. This is slow in docker and on windows. command = ['git', 'describe', '--abbrev=6', '--dirty', '--always', '--tags'] -result = subprocess.run(command, universal_newlines=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) +result = subprocess.run(command, universal_newlines=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) if result.returncode == 0: - os.environ['QMK_VERSION'] = 'QMK ' + result.stdout.strip() + os.environ['QMK_VERSION'] = result.stdout.strip() else: - os.environ['QMK_VERSION'] = 'QMK ' + strftime('%Y-%m-%d-%H:%M:%S') + os.environ['QMK_VERSION'] = 'nogit-' + strftime('%Y-%m-%d-%H:%M:%S') + '-dirty' # Setup the CLI import milc -milc.EMOJI_LOGLEVELS['INFO'] = '{fg_blue}Ψ{style_reset_all}' -# If we were invoked as `qmk ` massage sys.argv into `qmk-`. -# This means we can't accept arguments to the qmk script itself. -script_name = os.path.basename(sys.argv[0]) -if script_name == 'qmk': - if len(sys.argv) == 1: - milc.cli.log.error('No subcommand specified!\n') - - if len(sys.argv) == 1 or sys.argv[1] in ['-h', '--help']: - milc.cli.echo('usage: qmk [...]') - milc.cli.echo('\nsubcommands:') - subcommands = glob(os.path.join(qmk_dir, 'bin', 'qmk-*')) - for subcommand in sorted(subcommands): - subcommand = os.path.basename(subcommand).split('-', 1)[1] - milc.cli.echo('\t%s', subcommand) - milc.cli.echo('\nqmk --help for more information') - exit(1) +milc.EMOJI_LOGLEVELS['INFO'] = '{fg_blue}Ψ{style_reset_all}' - if sys.argv[1] in ['-V', '--version']: - milc.cli.echo(os.environ['QMK_VERSION']) - exit(0) - sys.argv[0] = script_name = '-'.join((script_name, sys.argv[1])) - del sys.argv[1] +@milc.cli.entrypoint('QMK Helper Script') +def qmk_main(cli): + """The function that gets run when no subcommand is provided. + """ + cli.print_help() -# Look for which module to import -if script_name == 'qmk': - milc.cli.print_help() - exit(0) -elif not script_name.startswith('qmk-'): - milc.cli.log.error('Invalid symlink, must start with "qmk-": %s', script_name) -else: - subcommand = script_name.replace('-', '.').replace('_', '.').split('.') - subcommand.insert(1, 'cli') - subcommand = '.'.join(subcommand) - try: - import_module(subcommand) - except ModuleNotFoundError as e: - if e.__class__.__name__ != subcommand: - raise +def main(): + """Setup our environment and then call the CLI entrypoint. + """ + # Change to the root of our checkout + os.environ['ORIG_CWD'] = os.getcwd() + os.chdir(qmk_dir) - milc.cli.log.error('Invalid subcommand! Could not import %s.', subcommand) - exit(1) + # Import the subcommands + import qmk.cli -if __name__ == '__main__': + # Execute return_code = milc.cli() + if return_code is False: exit(1) - elif return_code is not True and isinstance(return_code, int) and return_code < 256: + + elif return_code is not True and isinstance(return_code, int): + if return_code < 0 or return_code > 255: + milc.cli.log.error('Invalid return_code: %d', return_code) + exit(255) + exit(return_code) - else: - exit(0) + + exit(0) + + +if __name__ == '__main__': + main() diff --git a/bin/qmk-compile-json b/bin/qmk-compile-json deleted file mode 120000 index c92dce8a10..0000000000 --- a/bin/qmk-compile-json +++ /dev/null @@ -1 +0,0 @@ -qmk \ No newline at end of file diff --git a/bin/qmk-doctor b/bin/qmk-doctor deleted file mode 120000 index c92dce8a10..0000000000 --- a/bin/qmk-doctor +++ /dev/null @@ -1 +0,0 @@ -qmk \ No newline at end of file diff --git a/bin/qmk-hello b/bin/qmk-hello deleted file mode 120000 index c92dce8a10..0000000000 --- a/bin/qmk-hello +++ /dev/null @@ -1 +0,0 @@ -qmk \ No newline at end of file diff --git a/bin/qmk-json-keymap b/bin/qmk-json-keymap deleted file mode 120000 index c92dce8a10..0000000000 --- a/bin/qmk-json-keymap +++ /dev/null @@ -1 +0,0 @@ -qmk \ No newline at end of file -- cgit v1.2.3 From 74252e03cfd2ee3d7ba823fb4c3ce522f43e79a0 Mon Sep 17 00:00:00 2001 From: fauxpark Date: Thu, 31 Oct 2019 16:50:45 +1100 Subject: Fix "could not find module" error message formatting (#7219) --- bin/qmk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'bin') diff --git a/bin/qmk b/bin/qmk index 876473fa43..5da8673ba0 100755 --- a/bin/qmk +++ b/bin/qmk @@ -26,7 +26,7 @@ with open(os.path.join(qmk_dir, 'requirements.txt'), 'r') as fd: module = line.split('=')[0] if '=' in line else line if not find_spec(module): - print('Could not find module %s!', module) + print('Could not find module %s!' % module) print('Please run `pip3 install -r requirements.txt` to install the python dependencies.') exit(255) -- cgit v1.2.3 From f7bdc54c697ff24bec1bd0781666ac05401bafb2 Mon Sep 17 00:00:00 2001 From: skullydazed Date: Wed, 20 Nov 2019 14:54:18 -0800 Subject: Add flake8 to our test suite and fix all errors (#7379) * Add flake8 to our test suite and fix all errors * Add some documentation --- bin/qmk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'bin') diff --git a/bin/qmk b/bin/qmk index 5da8673ba0..4d5b3d884f 100755 --- a/bin/qmk +++ b/bin/qmk @@ -41,7 +41,7 @@ else: os.environ['QMK_VERSION'] = 'nogit-' + strftime('%Y-%m-%d-%H:%M:%S') + '-dirty' # Setup the CLI -import milc +import milc # noqa milc.EMOJI_LOGLEVELS['INFO'] = '{fg_blue}Ψ{style_reset_all}' @@ -61,7 +61,7 @@ def main(): os.chdir(qmk_dir) # Import the subcommands - import qmk.cli + import qmk.cli # noqa # Execute return_code = milc.cli() -- cgit v1.2.3