aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/cli.md24
-rw-r--r--lib/python/qmk/cli/__init__.py1
-rwxr-xr-xlib/python/qmk/cli/compile.py14
-rw-r--r--lib/python/qmk/cli/flash.py87
-rw-r--r--lib/python/qmk/commands.py57
-rw-r--r--lib/python/qmk/tests/test_cli_commands.py3
6 files changed, 181 insertions, 5 deletions
diff --git a/docs/cli.md b/docs/cli.md
index fb7d17d2a..1c0952722 100644
--- a/docs/cli.md
+++ b/docs/cli.md
@@ -95,6 +95,30 @@ qmk compile <configuratorExport.json>
95qmk compile -kb <keyboard_name> -km <keymap_name> 95qmk compile -kb <keyboard_name> -km <keymap_name>
96``` 96```
97 97
98## `qmk flash`
99
100This command is similar to `qmk compile`, but can also target a bootloader. The bootloader is optional, and is set to `:flash` by default.
101To specify a different bootloader, use `-bl <bootloader>`. Visit <https://docs.qmk.fm/#/flashing>
102for more details of the available bootloaders.
103
104**Usage for Configurator Exports**:
105
106```
107qmk flash <configuratorExport.json> -bl <bootloader>
108```
109
110**Usage for Keymaps**:
111
112```
113qmk flash -kb <keyboard_name> -km <keymap_name> -bl <bootloader>
114```
115
116**Listing the Bootloaders**
117
118```
119qmk flash -b
120```
121
98## `qmk config` 122## `qmk config`
99 123
100This command lets you configure the behavior of QMK. For the full `qmk config` documentation see [CLI Configuration](cli_configuration.md). 124This command lets you configure the behavior of QMK. For the full `qmk config` documentation see [CLI Configuration](cli_configuration.md).
diff --git a/lib/python/qmk/cli/__init__.py b/lib/python/qmk/cli/__init__.py
index 1b83e78c7..72ee38f56 100644
--- a/lib/python/qmk/cli/__init__.py
+++ b/lib/python/qmk/cli/__init__.py
@@ -7,6 +7,7 @@ from . import compile
7from . import config 7from . import config
8from . import docs 8from . import docs
9from . import doctor 9from . import doctor
10from . import flash
10from . import hello 11from . import hello
11from . import json 12from . import json
12from . import list 13from . import list
diff --git a/lib/python/qmk/cli/compile.py b/lib/python/qmk/cli/compile.py
index 6646891b3..c7093d421 100755
--- a/lib/python/qmk/cli/compile.py
+++ b/lib/python/qmk/cli/compile.py
@@ -9,6 +9,9 @@ import subprocess
9from argparse import FileType 9from argparse import FileType
10 10
11from milc import cli 11from milc import cli
12from qmk.commands import create_make_command
13from qmk.commands import parse_configurator_json
14from qmk.commands import compile_configurator_json
12 15
13import qmk.keymap 16import qmk.keymap
14import qmk.path 17import qmk.path
@@ -30,20 +33,21 @@ def compile(cli):
30 """ 33 """
31 if cli.args.filename: 34 if cli.args.filename:
32 # Parse the configurator json 35 # Parse the configurator json
33 user_keymap = json.load(cli.args.filename) 36 user_keymap = parse_configurator_json(cli.args.filename)
34 37
35 # Generate the keymap 38 # Generate the keymap
36 keymap_path = qmk.path.keymap(user_keymap['keyboard']) 39 keymap_path = qmk.path.keymap(user_keymap['keyboard'])
37 cli.log.info('Creating {fg_cyan}%s{style_reset_all} keymap in {fg_cyan}%s', user_keymap['keymap'], keymap_path) 40 cli.log.info('Creating {fg_cyan}%s{style_reset_all} keymap in {fg_cyan}%s', user_keymap['keymap'], keymap_path)
38 qmk.keymap.write(user_keymap['keyboard'], user_keymap['keymap'], user_keymap['layout'], user_keymap['layers']) 41
42 # Compile the keymap
43 command = compile_configurator_json(cli.args.filename)
44
39 cli.log.info('Wrote keymap to {fg_cyan}%s/%s/keymap.c', keymap_path, user_keymap['keymap']) 45 cli.log.info('Wrote keymap to {fg_cyan}%s/%s/keymap.c', keymap_path, user_keymap['keymap'])
40 46
41 # Compile the keymap
42 command = ['make', ':'.join((user_keymap['keyboard'], user_keymap['keymap']))]
43 47
44 elif cli.config.compile.keyboard and cli.config.compile.keymap: 48 elif cli.config.compile.keyboard and cli.config.compile.keymap:
45 # Generate the make command for a specific keyboard/keymap. 49 # Generate the make command for a specific keyboard/keymap.
46 command = ['make', ':'.join((cli.config.compile.keyboard, cli.config.compile.keymap))] 50 command = create_make_command(cli.config.compile.keyboard, cli.config.compile.keymap)
47 51
48 else: 52 else:
49 cli.log.error('You must supply a configurator export or both `--keyboard` and `--keymap`.') 53 cli.log.error('You must supply a configurator export or both `--keyboard` and `--keymap`.')
diff --git a/lib/python/qmk/cli/flash.py b/lib/python/qmk/cli/flash.py
new file mode 100644
index 000000000..8f7bb55a2
--- /dev/null
+++ b/lib/python/qmk/cli/flash.py
@@ -0,0 +1,87 @@
1"""Compile and flash QMK Firmware
2
3You can compile a keymap already in the repo or using a QMK Configurator export.
4A bootloader must be specified.
5"""
6import os
7import sys
8import subprocess
9from argparse import FileType
10
11from milc import cli
12from qmk.commands import create_make_command
13from qmk.commands import parse_configurator_json
14from qmk.commands import compile_configurator_json
15
16import qmk.path
17
18
19def print_bootloader_help():
20 """Prints the available bootloaders listed in docs.qmk.fm.
21 """
22 cli.log.info('Here are the available bootloaders:')
23 cli.echo('\tdfu')
24 cli.echo('\tdfu-ee')
25 cli.echo('\tdfu-split-left')
26 cli.echo('\tdfu-split-right')
27 cli.echo('\tavrdude')
28 cli.echo('\tBootloadHID')
29 cli.echo('\tdfu-util')
30 cli.echo('\tdfu-util-split-left')
31 cli.echo('\tdfu-util-split-right')
32 cli.echo('\tst-link-cli')
33 cli.echo('For more info, visit https://docs.qmk.fm/#/flashing')
34
35@cli.argument('-bl', '--bootloader', default='flash', help='The flash command, corresponding to qmk\'s make options of bootloaders.')
36@cli.argument('filename', nargs='?', arg_only=True, help='The configurator export JSON to compile. Use this if you dont want to specify a keymap and keyboard.')
37@cli.argument('-km', '--keymap', help='The keymap to build a firmware for. Use this if you dont have a configurator file. Ignored when a configurator file is supplied.')
38@cli.argument('-kb', '--keyboard', help='The keyboard to build a firmware for. Use this if you dont have a configurator file. Ignored when a configurator file is supplied.')
39@cli.argument('-b', '--bootloaders', action='store_true', help='List the available bootloaders.')
40@cli.subcommand('QMK Flash.')
41def flash(cli):
42 """Compile and or flash QMK Firmware or keyboard/layout
43
44 If a Configurator JSON export is supplied this command will create a new keymap. Keymap and Keyboard arguments
45 will be ignored.
46
47 If no file is supplied, keymap and keyboard are expected.
48
49 If bootloader is omitted, the one according to the rules.mk will be used.
50
51 """
52 command = []
53 if cli.args.bootloaders:
54 # Provide usage and list bootloaders
55 cli.echo('usage: qmk flash [-h] [-b] [-kb KEYBOARD] [-km KEYMAP] [-bl BOOTLOADER] [filename]')
56 print_bootloader_help()
57 return False
58
59 elif cli.args.keymap and not cli.args.keyboard:
60 # If only a keymap was given but no keyboard, suggest listing keyboards
61 cli.echo('usage: qmk flash [-h] [-b] [-kb KEYBOARD] [-km KEYMAP] [-bl BOOTLOADER] [filename]')
62 cli.log.error('run \'qmk list_keyboards\' to find out the supported keyboards')
63 return False
64
65 elif cli.args.filename:
66 # Get keymap path to log info
67 user_keymap = parse_configurator_json(cli.args.filename)
68 keymap_path = qmk.path.keymap(user_keymap['keyboard'])
69
70 cli.log.info('Creating {fg_cyan}%s{style_reset_all} keymap in {fg_cyan}%s', user_keymap['keymap'], keymap_path)
71
72 # Convert the JSON into a C file and write it to disk.
73 command = compile_configurator_json(cli.args.filename, cli.args.bootloader)
74
75 cli.log.info('Wrote keymap to {fg_cyan}%s/%s/keymap.c', keymap_path, user_keymap['keymap'])
76
77 elif cli.args.keyboard and cli.args.keymap:
78 # Generate the make command for a specific keyboard/keymap.
79 command = create_make_command(cli.config.flash.keyboard, cli.config.flash.keymap, cli.args.bootloader)
80
81 else:
82 cli.echo('usage: qmk flash [-h] [-b] [-kb KEYBOARD] [-km KEYMAP] [-bl BOOTLOADER] [filename]')
83 cli.log.error('You must supply a configurator export or both `--keyboard` and `--keymap`. You can also specify a bootloader with --bootloader. Use --bootloaders to list the available bootloaders.')
84 return False
85
86 cli.log.info('Flashing keymap with {fg_cyan}%s\n\n', ' '.join(command))
87 subprocess.run(command) \ No newline at end of file
diff --git a/lib/python/qmk/commands.py b/lib/python/qmk/commands.py
new file mode 100644
index 000000000..9fbf00f16
--- /dev/null
+++ b/lib/python/qmk/commands.py
@@ -0,0 +1,57 @@
1"""Functions that build make commands
2"""
3import json
4import qmk.keymap
5
6def create_make_command(keyboard, keymap, target=None):
7 """Create a make compile command
8
9 Args:
10 keyboard
11 The path of the keyboard, for example 'plank'
12
13 keymap
14 The name of the keymap, for example 'algernon'
15
16 target
17 Usually a bootloader.
18
19 Returns:
20 A command that can be run to make the specified keyboard and keymap
21 """
22 if target is None:
23 return ['make', ':'.join((keyboard, keymap))]
24 return ['make', ':'.join((keyboard, keymap, target))]
25
26def parse_configurator_json(configurator_filename):
27 """Open and parse a configurator json export
28 """
29 file = open(configurator_filename)
30 user_keymap = json.load(file)
31 file.close()
32 return user_keymap
33
34def compile_configurator_json(configurator_filename, bootloader=None):
35 """Convert a configurator export JSON file into a C file
36
37 Args:
38 configurator_filename
39 The configurator JSON export file
40
41 bootloader
42 A bootloader to flash
43
44 Returns:
45 A command to run to compile and flash the C file.
46 """
47 # Parse the configurator json
48 user_keymap = parse_configurator_json(configurator_filename)
49
50 # Write the keymap C file
51 qmk.keymap.write(user_keymap['keyboard'], user_keymap['keymap'], user_keymap['layout'], user_keymap['layers'])
52
53 # Return a command that can be run to make the keymap and flash if given
54 if bootloader is None:
55 return create_make_command(user_keymap['keyboard'], user_keymap['keymap'])
56 return create_make_command(user_keymap['keyboard'], user_keymap['keymap'], bootloader)
57
diff --git a/lib/python/qmk/tests/test_cli_commands.py b/lib/python/qmk/tests/test_cli_commands.py
index 85d4d91af..dcab8bdae 100644
--- a/lib/python/qmk/tests/test_cli_commands.py
+++ b/lib/python/qmk/tests/test_cli_commands.py
@@ -13,6 +13,9 @@ def test_cformat():
13def test_compile(): 13def test_compile():
14 assert check_subcommand('compile', '-kb', 'handwired/onekey/pytest', '-km', 'default').returncode == 0 14 assert check_subcommand('compile', '-kb', 'handwired/onekey/pytest', '-km', 'default').returncode == 0
15 15
16def test_flash():
17 assert check_subcommand('flash', '-b').returncode == 1
18 assert check_subcommand('flash').returncode == 1
16 19
17def test_config(): 20def test_config():
18 result = check_subcommand('config') 21 result = check_subcommand('config')