aboutsummaryrefslogtreecommitdiff
path: root/lib/python/qmk/cli
diff options
context:
space:
mode:
authorskullydazed <skullydazed@users.noreply.github.com>2020-02-17 11:42:11 -0800
committerGitHub <noreply@github.com>2020-02-17 11:42:11 -0800
commitc66930445f7d5941eb847568288046d51f853786 (patch)
tree273f290ca81a27bbbe7bdbf90221c02ac11f42cd /lib/python/qmk/cli
parent58724f8dcb9eccb1c132b8ddab422790ddd26be0 (diff)
downloadqmk_firmware-c66930445f7d5941eb847568288046d51f853786.tar.gz
qmk_firmware-c66930445f7d5941eb847568288046d51f853786.zip
Use pathlib everywhere we can (#7872)
* Use pathlib everywhere we can * Update lib/python/qmk/path.py Co-Authored-By: Erovia <Erovia@users.noreply.github.com> * Update lib/python/qmk/path.py Co-Authored-By: Erovia <Erovia@users.noreply.github.com> * Improvements based on @erovia's feedback * rework qmk compile and qmk flash to use pathlib * style * Remove the subcommand_name argument from find_keyboard_keymap() Co-authored-by: Erovia <Erovia@users.noreply.github.com>
Diffstat (limited to 'lib/python/qmk/cli')
-rwxr-xr-xlib/python/qmk/cli/compile.py99
-rw-r--r--lib/python/qmk/cli/flash.py34
-rwxr-xr-xlib/python/qmk/cli/json/keymap.py31
-rw-r--r--lib/python/qmk/cli/list/keyboards.py1
-rwxr-xr-xlib/python/qmk/cli/new/keymap.py26
5 files changed, 57 insertions, 134 deletions
diff --git a/lib/python/qmk/cli/compile.py b/lib/python/qmk/cli/compile.py
index 826b969ef..3068c97d8 100755
--- a/lib/python/qmk/cli/compile.py
+++ b/lib/python/qmk/cli/compile.py
@@ -3,16 +3,12 @@
3You can compile a keymap already in the repo or using a QMK Configurator export. 3You can compile a keymap already in the repo or using a QMK Configurator export.
4""" 4"""
5import subprocess 5import subprocess
6import os
7from argparse import FileType 6from argparse import FileType
8 7
9from milc import cli 8from milc import cli
10from qmk.commands import create_make_command
11from qmk.commands import parse_configurator_json
12from qmk.commands import compile_configurator_json
13 9
14import qmk.keymap
15import qmk.path 10import qmk.path
11from qmk.commands import compile_configurator_json, create_make_command, find_keyboard_keymap, parse_configurator_json
16 12
17 13
18@cli.argument('filename', nargs='?', arg_only=True, type=FileType('r'), help='The configurator export to compile') 14@cli.argument('filename', nargs='?', arg_only=True, type=FileType('r'), help='The configurator export to compile')
@@ -24,99 +20,28 @@ def compile(cli):
24 20
25 If a Configurator export is supplied this command will create a new keymap, overwriting an existing keymap if one exists. 21 If a Configurator export is supplied this command will create a new keymap, overwriting an existing keymap if one exists.
26 22
27 FIXME(skullydazed): add code to check and warn if the keymap already exists 23 If a keyboard and keymap are provided this command will build a firmware based on that.
28
29 If --keyboard and --keymap are provided this command will build a firmware based on that.
30
31 """ 24 """
32 # Set CWD as directory command was issued from
33 cwd = os.environ['ORIG_CWD']
34 qmk_path = os.getcwd()
35 current_folder = os.path.basename(cwd)
36 # Initialize boolean to check for being in a keyboard directory and initialize keyboard string
37 in_keyboard = False
38 in_layout = False
39 keyboard = ""
40 keymap = ""
41 user_keymap = ""
42 user_keyboard = ""
43
44 # Set path for '/keyboards/' directory
45 keyboards_path = os.path.join(qmk_path, "keyboards")
46 layouts_path = os.path.join(qmk_path, "layouts")
47
48 # If below 'keyboards' and not in 'keyboards' or 'keymaps', get current keyboard name
49 if cwd.startswith(keyboards_path):
50 if current_folder != "keyboards" and current_folder != "keymaps":
51 if os.path.basename(os.path.abspath(os.path.join(cwd, ".."))) == "keymaps":
52 # If in a keymap folder, set relative path, get everything before /keymaps, and the keymap name
53 relative_path = cwd[len(keyboards_path):][1:]
54 keyboard = str(relative_path).split("/keymaps", 1)[0]
55 keymap = str(relative_path.rsplit("/", 1)[-1])
56 else:
57 keyboard = str(cwd[len(keyboards_path):])[1:]
58
59 in_keyboard = True
60
61 # If in layouts dir
62 if cwd.startswith(layouts_path):
63 if current_folder != "layouts":
64 in_layout = True
65
66 # If user keyboard/keymap or compile keyboard/keymap are supplied, assign those
67 if cli.config.compile.keyboard:
68 user_keyboard = cli.config.compile.keyboard
69 if cli.config.compile.keymap and not in_layout:
70 user_keymap = cli.config.compile.keymap
71
72 if cli.args.filename: 25 if cli.args.filename:
73 # Parse the configurator json 26 # If a configurator JSON was provided skip straight to compiling it
27 # FIXME(skullydazed): add code to check and warn if the keymap already exists when compiling a json keymap.
74 user_keymap = parse_configurator_json(cli.args.filename) 28 user_keymap = parse_configurator_json(cli.args.filename)
75
76 # Generate the keymap
77 keymap_path = qmk.path.keymap(user_keymap['keyboard']) 29 keymap_path = qmk.path.keymap(user_keymap['keyboard'])
78 cli.log.info('Creating {fg_cyan}%s{style_reset_all} keymap in {fg_cyan}%s', user_keymap['keymap'], keymap_path)
79
80 # Compile the keymap
81 command = compile_configurator_json(user_keymap) 30 command = compile_configurator_json(user_keymap)
82 31
83 cli.log.info('Wrote keymap to {fg_cyan}%s/%s/keymap.c', keymap_path, user_keymap['keymap']) 32 cli.log.info('Wrote keymap to {fg_cyan}%s/%s/keymap.c', keymap_path, user_keymap['keymap'])
84 33
85 elif user_keyboard and user_keymap: 34 else:
86 # Generate the make command for a specific keyboard/keymap. 35 # Perform the action the user specified
87 command = create_make_command(user_keyboard, user_keymap) 36 user_keyboard, user_keymap = find_keyboard_keymap()
88 37 if user_keyboard and user_keymap:
89 elif in_keyboard: 38 # Generate the make command for a specific keyboard/keymap.
90 keyboard = user_keyboard if user_keyboard else keyboard 39 command = create_make_command(user_keyboard, user_keymap)
91 keymap = user_keymap if user_keymap else keymap
92
93 if not os.path.exists(os.path.join(keyboards_path, keyboard, "rules.mk")):
94 cli.log.error('This directory does not contain a rules.mk file. Change directory or supply --keyboard with optional --keymap')
95 return False
96
97 # Get path for keyboard directory
98 keymap_path = qmk.path.keymap(keyboard)
99
100 # Check for global keymap config first
101 if keymap:
102 command = create_make_command(keyboard, keymap)
103
104 else:
105 # If no default keymap exists and none provided
106 cli.log.error('This directory does not contain a keymap. Set one with `qmk config` or supply `--keymap` ')
107 return False
108 40
109 elif in_layout:
110 if user_keyboard:
111 keymap = current_folder
112 command = create_make_command(user_keyboard, keymap)
113 else: 41 else:
114 cli.log.error('You must supply a keyboard to compile a layout keymap. Set one with `qmk config` or supply `--keyboard` ') 42 cli.log.error('You must supply a configurator export, both `--keyboard` and `--keymap`, or be in a directory for a keyboard or keymap.')
43 cli.echo('usage: qmk compile [-h] [-b] [-kb KEYBOARD] [-km KEYMAP] [filename]')
115 return False 44 return False
116 45
117 else:
118 cli.log.error('You must supply a configurator export, both `--keyboard` and `--keymap`, or be in a directory for a keyboard or keymap.')
119 return False
120
121 cli.log.info('Compiling keymap with {fg_cyan}%s\n\n', ' '.join(command)) 46 cli.log.info('Compiling keymap with {fg_cyan}%s\n\n', ' '.join(command))
122 subprocess.run(command) 47 subprocess.run(command)
diff --git a/lib/python/qmk/cli/flash.py b/lib/python/qmk/cli/flash.py
index cc1e6235a..f669c3cb7 100644
--- a/lib/python/qmk/cli/flash.py
+++ b/lib/python/qmk/cli/flash.py
@@ -8,7 +8,7 @@ from argparse import FileType
8 8
9import qmk.path 9import qmk.path
10from milc import cli 10from milc import cli
11from qmk.commands import compile_configurator_json, create_make_command, parse_configurator_json 11from qmk.commands import compile_configurator_json, create_make_command, find_keyboard_keymap, parse_configurator_json
12 12
13 13
14def print_bootloader_help(): 14def print_bootloader_help():
@@ -45,39 +45,31 @@ def flash(cli):
45 If bootloader is omitted, the one according to the rules.mk will be used. 45 If bootloader is omitted, the one according to the rules.mk will be used.
46 46
47 """ 47 """
48 command = []
49 if cli.args.bootloaders: 48 if cli.args.bootloaders:
50 # Provide usage and list bootloaders 49 # Provide usage and list bootloaders
51 cli.echo('usage: qmk flash [-h] [-b] [-kb KEYBOARD] [-km KEYMAP] [-bl BOOTLOADER] [filename]') 50 cli.echo('usage: qmk flash [-h] [-b] [-kb KEYBOARD] [-km KEYMAP] [-bl BOOTLOADER] [filename]')
52 print_bootloader_help() 51 print_bootloader_help()
53 return False 52 return False
54 53
55 elif cli.config.flash.keymap and not cli.config.flash.keyboard: 54 if cli.args.filename:
56 # If only a keymap was given but no keyboard, suggest listing keyboards 55 # Handle compiling a configurator JSON
57 cli.echo('usage: qmk flash [-h] [-b] [-kb KEYBOARD] [-km KEYMAP] [-bl BOOTLOADER] [filename]')
58 cli.log.error('run \'qmk list_keyboards\' to find out the supported keyboards')
59 return False
60
61 elif cli.args.filename:
62 # Get keymap path to log info
63 user_keymap = parse_configurator_json(cli.args.filename) 56 user_keymap = parse_configurator_json(cli.args.filename)
64 keymap_path = qmk.path.keymap(user_keymap['keyboard']) 57 keymap_path = qmk.path.keymap(user_keymap['keyboard'])
65
66 cli.log.info('Creating {fg_cyan}%s{style_reset_all} keymap in {fg_cyan}%s', user_keymap['keymap'], keymap_path)
67
68 # Convert the JSON into a C file and write it to disk.
69 command = compile_configurator_json(user_keymap, cli.args.bootloader) 58 command = compile_configurator_json(user_keymap, cli.args.bootloader)
70 59
71 cli.log.info('Wrote keymap to {fg_cyan}%s/%s/keymap.c', keymap_path, user_keymap['keymap']) 60 cli.log.info('Wrote keymap to {fg_cyan}%s/%s/keymap.c', keymap_path, user_keymap['keymap'])
72 61
73 elif cli.config.flash.keyboard and cli.config.flash.keymap:
74 # Generate the make command for a specific keyboard/keymap.
75 command = create_make_command(cli.config.flash.keyboard, cli.config.flash.keymap, cli.args.bootloader)
76
77 else: 62 else:
78 cli.echo('usage: qmk flash [-h] [-b] [-kb KEYBOARD] [-km KEYMAP] [-bl BOOTLOADER] [filename]') 63 # Perform the action the user specified
79 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.') 64 user_keyboard, user_keymap = find_keyboard_keymap()
80 return False 65 if user_keyboard and user_keymap:
66 # Generate the make command for a specific keyboard/keymap.
67 command = create_make_command(user_keyboard, user_keymap, cli.args.bootloader)
68
69 else:
70 cli.log.error('You must supply a configurator export or both `--keyboard` and `--keymap`.')
71 cli.echo('usage: qmk flash [-h] [-b] [-kb KEYBOARD] [-km KEYMAP] [-bl BOOTLOADER] [filename]')
72 return False
81 73
82 cli.log.info('Flashing keymap with {fg_cyan}%s\n\n', ' '.join(command)) 74 cli.log.info('Flashing keymap with {fg_cyan}%s\n\n', ' '.join(command))
83 subprocess.run(command) 75 subprocess.run(command)
diff --git a/lib/python/qmk/cli/json/keymap.py b/lib/python/qmk/cli/json/keymap.py
index a030ab53d..c2b7dde7a 100755
--- a/lib/python/qmk/cli/json/keymap.py
+++ b/lib/python/qmk/cli/json/keymap.py
@@ -1,14 +1,15 @@
1"""Generate a keymap.c from a configurator export. 1"""Generate a keymap.c from a configurator export.
2""" 2"""
3import json 3import json
4import os 4from pathlib import Path
5 5
6from milc import cli 6from milc import cli
7 7
8import qmk.keymap 8import qmk.keymap
9import qmk.path
9 10
10 11
11@cli.argument('-o', '--output', arg_only=True, help='File to write to') 12@cli.argument('-o', '--output', arg_only=True, type=Path, help='File to write to')
12@cli.argument('-q', '--quiet', arg_only=True, action='store_true', help="Quiet mode, only output error messages") 13@cli.argument('-q', '--quiet', arg_only=True, action='store_true', help="Quiet mode, only output error messages")
13@cli.argument('filename', arg_only=True, help='Configurator JSON file') 14@cli.argument('filename', arg_only=True, help='Configurator JSON file')
14@cli.subcommand('Creates a keymap.c from a QMK Configurator export.') 15@cli.subcommand('Creates a keymap.c from a QMK Configurator export.')
@@ -17,13 +18,17 @@ def json_keymap(cli):
17 18
18 This command uses the `qmk.keymap` module to generate a keymap.c from a configurator export. The generated keymap is written to stdout, or to a file if -o is provided. 19 This command uses the `qmk.keymap` module to generate a keymap.c from a configurator export. The generated keymap is written to stdout, or to a file if -o is provided.
19 """ 20 """
21 cli.args.filename = qmk.path.normpath(cli.args.filename)
22
20 # Error checking 23 # Error checking
21 if cli.args.filename == ('-'): 24 if not cli.args.filename.exists():
22 cli.log.error('Reading from STDIN is not (yet) supported.') 25 cli.log.error('JSON file does not exist!')
23 cli.print_usage() 26 cli.print_usage()
24 exit(1) 27 exit(1)
25 if not os.path.exists(qmk.path.normpath(cli.args.filename)): 28
26 cli.log.error('JSON file does not exist!') 29 if str(cli.args.filename) == '-':
30 # TODO(skullydazed/anyone): Read file contents from STDIN
31 cli.log.error('Reading from STDIN is not (yet) supported.')
27 cli.print_usage() 32 cli.print_usage()
28 exit(1) 33 exit(1)
29 34
@@ -32,21 +37,17 @@ def json_keymap(cli):
32 cli.args.output = None 37 cli.args.output = None
33 38
34 # Parse the configurator json 39 # Parse the configurator json
35 with open(qmk.path.normpath(cli.args.filename), 'r') as fd: 40 with cli.args.filename.open('r') as fd:
36 user_keymap = json.load(fd) 41 user_keymap = json.load(fd)
37 42
38 # Generate the keymap 43 # Generate the keymap
39 keymap_c = qmk.keymap.generate(user_keymap['keyboard'], user_keymap['layout'], user_keymap['layers']) 44 keymap_c = qmk.keymap.generate(user_keymap['keyboard'], user_keymap['layout'], user_keymap['layers'])
40 45
41 if cli.args.output: 46 if cli.args.output:
42 output_dir = os.path.dirname(cli.args.output) 47 cli.args.output.parent.mkdir(parents=True, exist_ok=True)
43 48 if cli.args.output.exists():
44 if not os.path.exists(output_dir): 49 cli.args.output.replace(cli.args.output.name + '.bak')
45 os.makedirs(output_dir) 50 cli.args.output.write_text(keymap_c)
46
47 output_file = qmk.path.normpath(cli.args.output)
48 with open(output_file, 'w') as keymap_fd:
49 keymap_fd.write(keymap_c)
50 51
51 if not cli.args.quiet: 52 if not cli.args.quiet:
52 cli.log.info('Wrote keymap to %s.', cli.args.output) 53 cli.log.info('Wrote keymap to %s.', cli.args.output)
diff --git a/lib/python/qmk/cli/list/keyboards.py b/lib/python/qmk/cli/list/keyboards.py
index 76e7760e8..ca0c5661a 100644
--- a/lib/python/qmk/cli/list/keyboards.py
+++ b/lib/python/qmk/cli/list/keyboards.py
@@ -1,5 +1,6 @@
1"""List the keyboards currently defined within QMK 1"""List the keyboards currently defined within QMK
2""" 2"""
3# We avoid pathlib here because this is performance critical code.
3import os 4import os
4import glob 5import glob
5 6
diff --git a/lib/python/qmk/cli/new/keymap.py b/lib/python/qmk/cli/new/keymap.py
index 96525e28e..cbe50692e 100755
--- a/lib/python/qmk/cli/new/keymap.py
+++ b/lib/python/qmk/cli/new/keymap.py
@@ -1,8 +1,9 @@
1"""This script automates the copying of the default keymap into your own keymap. 1"""This script automates the copying of the default keymap into your own keymap.
2""" 2"""
3import os
4import shutil 3import shutil
4from pathlib import Path
5 5
6import qmk.path
6from milc import cli 7from milc import cli
7 8
8 9
@@ -17,24 +18,27 @@ def new_keymap(cli):
17 keymap = cli.config.new_keymap.keymap if cli.config.new_keymap.keymap else input("Keymap Name: ") 18 keymap = cli.config.new_keymap.keymap if cli.config.new_keymap.keymap else input("Keymap Name: ")
18 19
19 # generate keymap paths 20 # generate keymap paths
20 kb_path = os.path.join(os.getcwd(), "keyboards", keyboard) 21 kb_path = Path('keyboards') / keyboard
21 keymap_path_default = os.path.join(kb_path, "keymaps/default") 22 keymap_path = qmk.path.keymap(keyboard)
22 keymap_path = os.path.join(kb_path, "keymaps/%s" % keymap) 23 keymap_path_default = keymap_path / 'default'
24 keymap_path_new = keymap_path / keymap
23 25
24 # check directories 26 # check directories
25 if not os.path.exists(kb_path): 27 if not kb_path.exists():
26 cli.log.error('Keyboard %s does not exist!', kb_path) 28 cli.log.error('Keyboard %s does not exist!', kb_path)
27 exit(1) 29 exit(1)
28 if not os.path.exists(keymap_path_default): 30
31 if not keymap_path_default.exists():
29 cli.log.error('Keyboard default %s does not exist!', keymap_path_default) 32 cli.log.error('Keyboard default %s does not exist!', keymap_path_default)
30 exit(1) 33 exit(1)
31 if os.path.exists(keymap_path): 34
32 cli.log.error('Keymap %s already exists!', keymap_path) 35 if keymap_path_new.exists():
36 cli.log.error('Keymap %s already exists!', keymap_path_new)
33 exit(1) 37 exit(1)
34 38
35 # create user directory with default keymap files 39 # create user directory with default keymap files
36 shutil.copytree(keymap_path_default, keymap_path, symlinks=True) 40 shutil.copytree(str(keymap_path_default), str(keymap_path_new), symlinks=True)
37 41
38 # end message to user 42 # end message to user
39 cli.log.info("%s keymap directory created in: %s", keymap, keymap_path) 43 cli.log.info("%s keymap directory created in: %s", keymap, keymap_path_new)
40 cli.log.info("Compile a firmware with your new keymap by typing: \n" + "qmk compile -kb %s -km %s", keyboard, keymap) 44 cli.log.info("Compile a firmware with your new keymap by typing: \n\n\tqmk compile -kb %s -km %s\n", keyboard, keymap)