aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xbin/qmk62
-rw-r--r--docs/cli.md250
-rw-r--r--docs/cli_development.md2
-rwxr-xr-xlib/python/qmk/cli/hello.py2
-rwxr-xr-xlib/python/qmk/cli/pyformat.py2
-rw-r--r--lib/python/qmk/cli/pytest.py2
-rw-r--r--requirements-dev.txt4
-rw-r--r--requirements.txt3
8 files changed, 302 insertions, 25 deletions
diff --git a/bin/qmk b/bin/qmk
index 7592eefd9..e4fb057ff 100755
--- a/bin/qmk
+++ b/bin/qmk
@@ -4,34 +4,58 @@
4import os 4import os
5import sys 5import sys
6from importlib.util import find_spec 6from importlib.util import find_spec
7from time import strftime
8from pathlib import Path
7 9
8# Add the QMK python libs to our path 10# Add the QMK python libs to our path
9script_dir = os.path.dirname(os.path.realpath(__file__)) 11script_dir = Path(os.path.realpath(__file__)).parent
10qmk_dir = os.path.abspath(os.path.join(script_dir, '..')) 12qmk_dir = script_dir.parent
11python_lib_dir = os.path.abspath(os.path.join(qmk_dir, 'lib', 'python')) 13python_lib_dir = Path(qmk_dir / 'lib' / 'python').resolve()
12sys.path.append(python_lib_dir) 14sys.path.append(str(python_lib_dir))
15
16# QMK CLI user config file
17config_file = Path(Path.home() / '.config/qmk/qmk.ini')
13 18
14# Make sure our modules have been setup
15with open(os.path.join(qmk_dir, 'requirements.txt'), 'r') as fd:
16 for line in fd.readlines():
17 line = line.strip().replace('<', '=').replace('>', '=')
18 19
19 if line[0] == '#': 20def _check_modules(requirements):
20 continue 21 """ Check if the modules in the given requirements.txt are available.
22 """
23 with Path(qmk_dir / requirements).open() as fd:
24 for line in fd.readlines():
25 line = line.strip().replace('<', '=').replace('>', '=')
21 26
22 if '#' in line: 27 if line[0] == '#':
23 line = line.split('#')[0] 28 continue
24 29
25 module = line.split('=')[0] if '=' in line else line 30 if '#' in line:
31 line = line.split('#')[0]
32
33 module = dict()
34 module['name'] = module['import'] = line.split('=')[0] if '=' in line else line
26 35
27 if module in ['pep8-naming']:
28 # Not every module is importable by its own name. 36 # Not every module is importable by its own name.
29 continue 37 if module['name'] == "pep8-naming":
38 module['import'] = "pep8ext_naming"
30 39
31 if not find_spec(module): 40 if not find_spec(module['import']):
32 print('Could not find module %s!' % module) 41 print('Could not find module %s!' % module['name'])
33 print('Please run `pip3 install -r requirements.txt` to install the python dependencies.') 42 if developer:
34 exit(255) 43 print('Please run `pip3 install -r requirements-dev.txt` to install the python development dependencies or turn off developer mode with `qmk config user.developer=None`.')
44 print()
45 else:
46 print('Please run `pip3 install -r requirements.txt` to install the python dependencies.')
47 print()
48 exit(255)
49
50
51developer = False
52# Make sure our modules have been setup
53_check_modules('requirements.txt')
54
55# For developers additional modules are needed
56if config_file.exists() and 'developer = True' in config_file.read_text():
57 developer = True
58 _check_modules('requirements-dev.txt')
35 59
36# Setup the CLI 60# Setup the CLI
37import milc # noqa 61import milc # noqa
diff --git a/docs/cli.md b/docs/cli.md
index 760fe1cdb..625ac4fb7 100644
--- a/docs/cli.md
+++ b/docs/cli.md
@@ -37,3 +37,253 @@ We are looking for people to create and maintain a `qmk` package for more operat
37 * Document why in a comment when you do deviate 37 * Document why in a comment when you do deviate
38* Install using a virtualenv 38* Install using a virtualenv
39* Instruct the user to set the environment variable `QMK_HOME` to have the firmware source checked out somewhere other than `~/qmk_firmware`. 39* Instruct the user to set the environment variable `QMK_HOME` to have the firmware source checked out somewhere other than `~/qmk_firmware`.
40
41# Local CLI
42
43If you do not want to use the global CLI there is a local CLI bundled with `qmk_firmware`. You can find it in `qmk_firmware/bin/qmk`. You can run the `qmk` command from any directory and it will always operate on that copy of `qmk_firmware`.
44
45**Example**:
46
47```
48$ ~/qmk_firmware/bin/qmk hello
49Ψ Hello, World!
50```
51
52## Local CLI Limitations
53
54There are some limitations to the local CLI compared to the global CLI:
55
56* The local CLI does not support `qmk setup` or `qmk clone`
57* The local CLI always operates on the same `qmk_firmware` tree, even if you have multiple repositories cloned.
58* The local CLI does not run in a virtualenv, so it's possible that dependencies will conflict
59
60# CLI Commands
61
62## `qmk cformat`
63
64*dev mode*
65
66This command formats C code using clang-format. Run it with no arguments to format all core code, or pass filenames on the command line to run it on specific files.
67
68**Usage**:
69
70```
71qmk cformat [file1] [file2] [...] [fileN]
72```
73
74## `qmk compile`
75
76This command allows you to compile firmware from any directory. You can compile JSON exports from <https://config.qmk.fm>, compile keymaps in the repo, or compile the keyboard in the current working directory.
77
78**Usage for Configurator Exports**:
79
80```
81qmk compile <configuratorExport.json>
82```
83
84**Usage for Keymaps**:
85
86```
87qmk compile -kb <keyboard_name> -km <keymap_name>
88```
89
90**Usage in Keyboard Directory**:
91
92Must be in keyboard directory with a default keymap, or in keymap directory for keyboard, or supply one with `--keymap <keymap_name>`
93```
94qmk compile
95```
96
97**Example**:
98```
99$ qmk config compile.keymap=default
100$ cd ~/qmk_firmware/keyboards/planck/rev6
101$ qmk compile
102Ψ Compiling keymap with make planck/rev6:default
103...
104```
105or with optional keymap argument
106
107```
108$ cd ~/qmk_firmware/keyboards/clueboard/66/rev4
109$ qmk compile -km 66_iso
110Ψ Compiling keymap with make clueboard/66/rev4:66_iso
111...
112```
113or in keymap directory
114
115```
116$ cd ~/qmk_firmware/keyboards/gh60/satan/keymaps/colemak
117$ qmk compile
118Ψ Compiling keymap with make make gh60/satan:colemak
119...
120```
121
122**Usage in Layout Directory**:
123
124Must be under `qmk_firmware/layouts/`, and in a keymap folder.
125```
126qmk compile -kb <keyboard_name>
127```
128
129**Example**:
130```
131$ cd ~/qmk_firmware/layouts/community/60_ansi/mechmerlin-ansi
132$ qmk compile -kb dz60
133Ψ Compiling keymap with make dz60:mechmerlin-ansi
134...
135```
136
137## `qmk flash`
138
139This command is similar to `qmk compile`, but can also target a bootloader. The bootloader is optional, and is set to `:flash` by default.
140To specify a different bootloader, use `-bl <bootloader>`. Visit <https://docs.qmk.fm/#/flashing>
141for more details of the available bootloaders.
142
143**Usage for Configurator Exports**:
144
145```
146qmk flash <configuratorExport.json> -bl <bootloader>
147```
148
149**Usage for Keymaps**:
150
151```
152qmk flash -kb <keyboard_name> -km <keymap_name> -bl <bootloader>
153```
154
155**Listing the Bootloaders**
156
157```
158qmk flash -b
159```
160
161## `qmk config`
162
163This command lets you configure the behavior of QMK. For the full `qmk config` documentation see [CLI Configuration](cli_configuration.md).
164
165**Usage**:
166
167```
168qmk config [-ro] [config_token1] [config_token2] [...] [config_tokenN]
169```
170
171## `qmk docs`
172
173This command starts a local HTTP server which you can use for browsing or improving the docs. Default port is 8936.
174
175**Usage**:
176
177```
178qmk docs [-p PORT]
179```
180
181## `qmk doctor`
182
183This command examines your environment and alerts you to potential build or flash problems. It can fix many of them if you want it to.
184
185**Usage**:
186
187```
188qmk doctor [-y] [-n]
189```
190
191**Examples**:
192
193Check your environment for problems and prompt to fix them:
194
195 qmk doctor
196
197Check your environment and automatically fix any problems found:
198
199 qmk doctor -y
200
201Check your environment and report problems only:
202
203 qmk doctor -n
204
205## `qmk json-keymap`
206
207Creates a keymap.c from a QMK Configurator export.
208
209**Usage**:
210
211```
212qmk json-keymap [-o OUTPUT] filename
213```
214
215## `qmk kle2json`
216
217This command allows you to convert from raw KLE data to QMK Configurator JSON. It accepts either an absolute file path, or a file name in the current directory. By default it will not overwrite `info.json` if it is already present. Use the `-f` or `--force` flag to overwrite.
218
219**Usage**:
220
221```
222qmk kle2json [-f] <filename>
223```
224
225**Examples**:
226
227```
228$ qmk kle2json kle.txt
229☒ File info.json already exists, use -f or --force to overwrite.
230```
231
232```
233$ qmk kle2json -f kle.txt -f
234Ψ Wrote out to info.json
235```
236
237## `qmk list-keyboards`
238
239This command lists all the keyboards currently defined in `qmk_firmware`
240
241**Usage**:
242
243```
244qmk list-keyboards
245```
246
247## `qmk list-keymaps`
248
249This command lists all the keymaps for a specified keyboard (and revision).
250
251**Usage**:
252
253```
254qmk list-keymaps -kb planck/ez
255```
256
257## `qmk new-keymap`
258
259This command creates a new keymap based on a keyboard's existing default keymap.
260
261**Usage**:
262
263```
264qmk new-keymap [-kb KEYBOARD] [-km KEYMAP]
265```
266
267## `qmk pyformat`
268
269*dev mode*
270
271This command formats python code in `qmk_firmware`.
272
273**Usage**:
274
275```
276qmk pyformat
277```
278
279## `qmk pytest`
280
281*dev mode*
282
283This command runs the python test suite. If you make changes to python code you should ensure this runs successfully.
284
285**Usage**:
286
287```
288qmk pytest
289```
diff --git a/docs/cli_development.md b/docs/cli_development.md
index cc8c59d06..e41afc42f 100644
--- a/docs/cli_development.md
+++ b/docs/cli_development.md
@@ -6,6 +6,8 @@ This document has useful information for developers wishing to write new `qmk` s
6 6
7The QMK CLI operates using the subcommand pattern made famous by git. The main `qmk` script is simply there to setup the environment and pick the correct entrypoint to run. Each subcommand is a self-contained module with an entrypoint (decorated by `@cli.subcommand()`) that performs some action and returns a shell returncode, or None. 7The QMK CLI operates using the subcommand pattern made famous by git. The main `qmk` script is simply there to setup the environment and pick the correct entrypoint to run. Each subcommand is a self-contained module with an entrypoint (decorated by `@cli.subcommand()`) that performs some action and returns a shell returncode, or None.
8 8
9*Tip*: Enable dev mode by `qmk config user.developer=True`
10
9# Subcommands 11# Subcommands
10 12
11[MILC](https://github.com/clueboard/milc) is the CLI framework `qmk` uses to handle argument parsing, configuration, logging, and many other features. It lets you focus on writing your tool without wasting your time writing glue code. 13[MILC](https://github.com/clueboard/milc) is the CLI framework `qmk` uses to handle argument parsing, configuration, logging, and many other features. It lets you focus on writing your tool without wasting your time writing glue code.
diff --git a/lib/python/qmk/cli/hello.py b/lib/python/qmk/cli/hello.py
index bee28c301..5119188a0 100755
--- a/lib/python/qmk/cli/hello.py
+++ b/lib/python/qmk/cli/hello.py
@@ -6,7 +6,7 @@ from milc import cli
6 6
7 7
8@cli.argument('-n', '--name', default='World', help='Name to greet.') 8@cli.argument('-n', '--name', default='World', help='Name to greet.')
9@cli.subcommand('QMK Hello World.') 9@cli.subcommand('QMK Hello World.', hidden=False if cli.config.user.developer else True)
10def hello(cli): 10def hello(cli):
11 """Log a friendly greeting. 11 """Log a friendly greeting.
12 """ 12 """
diff --git a/lib/python/qmk/cli/pyformat.py b/lib/python/qmk/cli/pyformat.py
index a53ba40c0..146444380 100755
--- a/lib/python/qmk/cli/pyformat.py
+++ b/lib/python/qmk/cli/pyformat.py
@@ -5,7 +5,7 @@ from milc import cli
5import subprocess 5import subprocess
6 6
7 7
8@cli.subcommand("Format python code according to QMK's style.") 8@cli.subcommand("Format python code according to QMK's style.", hidden=False if cli.config.user.developer else True)
9def pyformat(cli): 9def pyformat(cli):
10 """Format python code according to QMK's style. 10 """Format python code according to QMK's style.
11 """ 11 """
diff --git a/lib/python/qmk/cli/pytest.py b/lib/python/qmk/cli/pytest.py
index 09611d750..5417a9cb3 100644
--- a/lib/python/qmk/cli/pytest.py
+++ b/lib/python/qmk/cli/pytest.py
@@ -7,7 +7,7 @@ import subprocess
7from milc import cli 7from milc import cli
8 8
9 9
10@cli.subcommand('QMK Python Unit Tests') 10@cli.subcommand('QMK Python Unit Tests', hidden=False if cli.config.user.developer else True)
11def pytest(cli): 11def pytest(cli):
12 """Run several linting/testing commands. 12 """Run several linting/testing commands.
13 """ 13 """
diff --git a/requirements-dev.txt b/requirements-dev.txt
new file mode 100644
index 000000000..deab419cb
--- /dev/null
+++ b/requirements-dev.txt
@@ -0,0 +1,4 @@
1# Python development requirements
2nose2
3flake8
4pep8-naming
diff --git a/requirements.txt b/requirements.txt
index 074b11a8c..aa6ee1ba3 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -4,6 +4,3 @@ appdirs
4argcomplete 4argcomplete
5colorama 5colorama
6hjson 6hjson
7nose2
8flake8
9pep8-naming