Compare commits

...

242 Commits

Author SHA1 Message Date
zvecr ebfc4e5812 Align git helper funcs 2026-07-02 23:13:45 +01:00
zvecr 33eddecd6e shell cleanup should quote TMPDIR defensively 2026-07-02 06:08:25 +01:00
zvecr ee779cec4d Fix git_clone_fork exit code regression 2026-07-01 04:25:50 +01:00
zvecr df7bd253d4 Add initial test suite 2026-07-01 03:04:46 +01:00
Joel Challis 8c6339493d Handle errors on Windows where some of the files have their read-only bit set (#242) 2026-07-01 02:48:30 +01:00
Joel Challis b87b18e9d4 Delete .flake8 2026-07-01 01:01:34 +01:00
Joel Challis e7b88acea2 Update docker workflow to actually run tests inside built container (#237) 2026-06-29 07:44:33 +01:00
Joel Challis 45c8ad6709 Run test script on Windows (#241) 2026-06-29 06:28:53 +01:00
Joel Challis 2116dd9582 Migrate to ruff for python linting (#240) 2026-06-29 06:10:55 +01:00
Joel Challis 05d1c36f49 Migrate setup.cfg to pyproject.toml (#236) 2026-06-29 04:07:19 +01:00
Joel Challis 5e57fdefe0 Add 'slim' container (#231) 2026-06-29 04:06:02 +01:00
dependabot[bot] af2ef5d90f Bump actions/checkout from 6 to 7 (#239)
Bumps [actions/checkout](https://github.com/actions/checkout) from 6 to 7.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v6...v7)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-20 23:56:18 +01:00
Joel Challis 1f6bb7dab0 Fix badge link in README.md 2026-04-21 00:45:36 +01:00
Joel Challis 2eb3279945 Align README with other repos 2026-04-21 00:41:11 +01:00
Joel Challis 8fd7af98d9 Remove qmk_fpm references (#233) 2026-04-21 00:21:40 +01:00
Joel Challis 240ccd781a Remove the release script 2026-04-21 00:18:36 +01:00
Joel Challis af9e8063f6 Remove Windows environment checks (#232) 2026-04-20 18:18:03 +01:00
dependabot[bot] 3054dad82b Bump docker/setup-buildx-action from 3 to 4 (#226)
Bumps [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) from 3 to 4.
- [Release notes](https://github.com/docker/setup-buildx-action/releases)
- [Commits](https://github.com/docker/setup-buildx-action/compare/v3...v4)

---
updated-dependencies:
- dependency-name: docker/setup-buildx-action
  dependency-version: '4'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-13 20:45:31 +00:00
dependabot[bot] 39a271132b Bump docker/build-push-action from 6.18.0 to 7.0.0 (#227)
* Bump docker/build-push-action from 6.18.0 to 7.0.0

Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 6.18.0 to 7.0.0.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/v6.18.0...v7.0.0)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-version: 7.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

* Apply suggestions from code review

Co-authored-by: Joel Challis <git@zvecr.com>

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Joel Challis <git@zvecr.com>
2026-03-13 20:45:16 +00:00
dependabot[bot] c19c21449e Bump docker/login-action from 3 to 4 (#225)
Bumps [docker/login-action](https://github.com/docker/login-action) from 3 to 4.
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](https://github.com/docker/login-action/compare/v3...v4)

---
updated-dependencies:
- dependency-name: docker/login-action
  dependency-version: '4'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-13 20:44:55 +00:00
dependabot[bot] f245cb7899 Bump docker/setup-qemu-action from 3 to 4 (#224)
Bumps [docker/setup-qemu-action](https://github.com/docker/setup-qemu-action) from 3 to 4.
- [Release notes](https://github.com/docker/setup-qemu-action/releases)
- [Commits](https://github.com/docker/setup-qemu-action/compare/v3...v4)

---
updated-dependencies:
- dependency-name: docker/setup-qemu-action
  dependency-version: '4'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-13 20:44:19 +00:00
dependabot[bot] 0b5866159a Bump WyriHaximus/github-action-get-previous-tag from 1 to 2 (#221)
Bumps [WyriHaximus/github-action-get-previous-tag](https://github.com/wyrihaximus/github-action-get-previous-tag) from 1 to 2.
- [Release notes](https://github.com/wyrihaximus/github-action-get-previous-tag/releases)
- [Commits](https://github.com/wyrihaximus/github-action-get-previous-tag/compare/v1...v2)

---
updated-dependencies:
- dependency-name: WyriHaximus/github-action-get-previous-tag
  dependency-version: '2'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-13 20:44:01 +00:00
QMK Bot 0dd2280781 New release: 1.1.8 → 1.2.0 2025-11-27 12:59:23 +00:00
Nick Brassel c049da0c6f Align QMK distrib search with qmk_firmware. (#219) 2025-11-27 23:35:47 +11:00
Joel Challis 7b69bd6f11 Align published container tags (#218) 2025-11-27 22:37:12 +11:00
Joel Challis c594e5df09 Build Dockerfile for PRs (#217) 2025-11-27 22:36:57 +11:00
Joel Challis 915bb40473 Align order of userspace search (#205) 2025-11-27 22:36:42 +11:00
Joel Challis af1403fc41 Fix relative paths if qmk_firmware exists elsewhere (#206) 2025-11-27 22:36:27 +11:00
Nick Brassel 13e5f5c855 Global install of QMK bootstrap distribution. (#216) 2025-11-27 07:07:38 +00:00
Nick Brassel f393ad0053 Use bootstrapper for build environment installation. (#210)
* Use bootstrapper for build environment installation.

* Publishing tags.

* Path.

* Minimisation of final image.

* Minimisation of final image.

* QMK distribution $PATH manipulation, to match qmk_firmware.

* QMK distribution $PATH manipulation, to match qmk_firmware.

* Fixup library search path on macOS.

* Escape hatch for path prefix.

* Add new environment variables.
2025-11-26 07:28:03 +11:00
dependabot[bot] 947e49a15d Bump actions/checkout from 5 to 6 (#214)
Bumps [actions/checkout](https://github.com/actions/checkout) from 5 to 6.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-25 19:51:30 +00:00
dependabot[bot] cd3ed07cd0 Bump github/codeql-action from 3 to 4 (#213)
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3 to 4.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/v3...v4)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-version: '4'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-16 00:35:07 +01:00
dependabot[bot] 558e248e20 Bump actions/setup-python from 5 to 6 (#212)
Bumps [actions/setup-python](https://github.com/actions/setup-python) from 5 to 6.
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](https://github.com/actions/setup-python/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/setup-python
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-15 22:56:37 +01:00
dependabot[bot] cd1e98e9d0 Bump actions/checkout from 4 to 5 (#211)
Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 5.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-15 22:54:34 +01:00
dependabot[bot] 8c2ae297ed Bump docker/build-push-action from 6.16.0 to 6.18.0 (#208)
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 6.16.0 to 6.18.0.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/v6.16.0...v6.18.0)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-version: 6.18.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-07-11 19:20:56 +01:00
QMK Bot 7be310f364 New release: 1.1.7 → 1.1.8 2025-05-28 13:14:51 +00:00
Nick Brassel 2316a34ce9 Hope this works. (#209) 2025-05-28 23:13:37 +10:00
dependabot[bot] 36c23e3de6 Bump docker/build-push-action from 6.15.0 to 6.16.0 (#204)
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 6.15.0 to 6.16.0.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/v6.15.0...v6.16.0)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-version: 6.16.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-27 00:33:51 +01:00
QMK Bot b6bc144e9e New release: 1.1.6 → 1.1.7 2025-04-21 23:39:00 +00:00
Agathe 93e629608e setup.cfg: drop setuptools dependency (#187)
The setuptools dependency is not needed in this file because setuptools
will be installed from the pyproject.toml file. Since the project does
not use anything from the setuptools package, remove it as a dependency.

This fixes the following bug in Debian:
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1083736
2025-04-21 19:18:46 +01:00
Nick Brassel cacd0fabbc Merge pull request #203 from qmk/windows-uv-compat 2025-04-22 00:14:36 +10:00
Nick Brassel d9f9b5a27d Path characters. 2025-04-11 22:03:14 +10:00
Nick Brassel 4d4892f58a Windows uv compat. 2025-03-31 14:18:39 +11:00
dependabot[bot] ffe20fb63e Bump docker/build-push-action from 6.13.0 to 6.15.0 (#200) 2025-03-02 17:38:01 +11:00
dependabot[bot] b384f871e8 Bump docker/build-push-action from 6.9.0 to 6.13.0 (#196)
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 6.9.0 to 6.13.0.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/v6.9.0...v6.13.0)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-01 13:28:19 +00:00
Joel Challis f2b8522c89 Fix test_cli_win test matrix (#197) 2025-02-01 13:12:55 +00:00
Joel Challis 75dcb0e475 Correct use of lru_cache for helpers (#189) 2024-11-15 06:51:59 +00:00
Nick Brassel 1e98a2e459 Broken CI. 2024-11-15 06:42:33 +11:00
Nick Brassel c53fb88479 Merge pull request #186 from qmk/found-repo-prompt 2024-11-15 06:14:09 +11:00
Nick Brassel fed1e39611 Merge pull request #168 from qmk/userspace1 2024-11-15 06:13:00 +11:00
QMK Bot ed0d5699ff New release: 1.1.5 → 1.1.6 2024-10-30 04:09:20 +00:00
Joel Challis b1542e4a62 Update build status badge 2024-10-28 02:43:10 +00:00
dependabot[bot] 9c7c371419 Bump github/codeql-action from 2 to 3 (#164)
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 2 to 3.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/v2...v3)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-27 05:01:35 +00:00
zvecr ae45bdeb02 Update 'qmk env' 2024-10-27 05:00:54 +00:00
zvecr d20af71118 Automatically configure userspace at runtime 2024-10-27 05:00:54 +00:00
Joel Challis 8f85a8856f Update for milc 1.9.0 changes (#184) 2024-10-27 04:59:42 +00:00
dependabot[bot] 87c356773f Bump docker/build-push-action from 5.1.0 to 6.9.0 (#185)
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 5.1.0 to 6.9.0.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/v5.1.0...v6.9.0)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-27 04:58:53 +00:00
fauxpark 27a97e4ebf qmk setup: ask user what to do if repo already exists 2024-10-27 15:52:52 +11:00
Wilhelm Schuster 53d8dab86f console: Adjust format string for could-not-connect message (#181) 2024-10-27 04:43:21 +00:00
Joel Challis 86a3decd0a Bump minimum Python version to 3.9 (#178) 2024-10-27 04:36:55 +00:00
QMK Bot d3917b10e7 New release: 1.1.4 → 1.1.5 2024-02-23 11:03:39 +00:00
Nick Brassel 86b3b74b21 Fixup package rebuild trigger for qmk_fpm. 2024-02-23 22:02:32 +11:00
QMK Bot bb385f7786 New release: 1.1.3 → 1.1.4 2024-02-23 10:57:48 +00:00
Nick Brassel e07ad4c9ee Swap to API token publishing. 2024-02-23 21:55:17 +11:00
QMK Bot 1e03b45986 New release: 1.1.2 → 1.1.3 2024-02-23 10:36:17 +00:00
Nick Brassel 7a1b556b25 Merge pull request #162 from qmk/pyvers 2024-02-23 21:34:58 +11:00
Nick Brassel d7911ffaf7 Disable qmk config -a test due to deficient milc. 2024-02-23 21:10:12 +11:00
Nick Brassel daa7f54dd0 milc bump to 1.6.8, add python 3.10-3.12. 2024-02-23 21:10:12 +11:00
dependabot[bot] 753136ade4 Bump actions/setup-python from 4 to 5 (#163) 2023-12-13 13:09:11 +11:00
Nick Brassel 579763620d Merge pull request #161 from qmk/dependabot/github_actions/docker/build-push-action-5.1.0 2023-11-30 19:52:19 +11:00
dependabot[bot] cbc22adb76 Bump docker/build-push-action from 5.0.0 to 5.1.0
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 5.0.0 to 5.1.0.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/v5.0.0...v5.1.0)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-17 17:07:56 +00:00
Less/Rikki 82bb65bd52 feat: wb32 bootloader (#148) 2023-09-29 12:04:47 +01:00
Nick Brassel 671e553239 Merge pull request #156 from qmk/dependabot/github_actions/docker/setup-buildx-action-3 2023-09-22 07:07:40 +10:00
Nick Brassel fa4bcc034d Merge pull request #157 from qmk/dependabot/github_actions/docker/setup-qemu-action-3 2023-09-22 07:07:26 +10:00
Nick Brassel 0a048da8a4 Merge pull request #155 from qmk/dependabot/github_actions/docker/login-action-3 2023-09-22 07:07:17 +10:00
Nick Brassel 7808a1166c Merge pull request #158 from qmk/dependabot/github_actions/docker/build-push-action-5.0.0 2023-09-22 07:07:06 +10:00
Nick Brassel b9b2ebbe13 Merge pull request #153 from qmk/dependabot/github_actions/actions/checkout-4 2023-09-22 07:06:55 +10:00
dependabot[bot] b4b53e80eb Bump docker/build-push-action from 4.1.1 to 5.0.0
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 4.1.1 to 5.0.0.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/v4.1.1...v5.0.0)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-12 17:40:58 +00:00
dependabot[bot] 2212fdabf7 Bump docker/setup-qemu-action from 2 to 3
Bumps [docker/setup-qemu-action](https://github.com/docker/setup-qemu-action) from 2 to 3.
- [Release notes](https://github.com/docker/setup-qemu-action/releases)
- [Commits](https://github.com/docker/setup-qemu-action/compare/v2...v3)

---
updated-dependencies:
- dependency-name: docker/setup-qemu-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-12 17:40:53 +00:00
dependabot[bot] 1e8a174e0c Bump docker/setup-buildx-action from 2 to 3
Bumps [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) from 2 to 3.
- [Release notes](https://github.com/docker/setup-buildx-action/releases)
- [Commits](https://github.com/docker/setup-buildx-action/compare/v2...v3)

---
updated-dependencies:
- dependency-name: docker/setup-buildx-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-12 17:40:48 +00:00
dependabot[bot] 6868d5ba6f Bump docker/login-action from 2 to 3
Bumps [docker/login-action](https://github.com/docker/login-action) from 2 to 3.
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](https://github.com/docker/login-action/compare/v2...v3)

---
updated-dependencies:
- dependency-name: docker/login-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-12 17:40:41 +00:00
dependabot[bot] e203006537 Bump actions/checkout from 3 to 4
Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 4.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v3...v4)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-04 17:05:56 +00:00
dependabot[bot] 1c72e1e564 Bump docker/build-push-action from 4.0.0 to 4.1.1 (#149)
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 4.0.0 to 4.1.1.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/v4.0.0...v4.1.1)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-06-14 04:16:53 +10:00
QMK Bot aecd02e850 New release: 1.1.1 → 1.1.2 2023-04-05 10:05:42 +00:00
Nick Brassel 5019970d01 Merge pull request #145 from qmk/attempted-formatting-fix 2023-04-05 20:04:23 +10:00
Nick Brassel 446547df04 Update qmk_cli/subcommands/console.py
Co-authored-by: Sergey Vlasov <sigprof@gmail.com>
2023-04-05 18:07:39 +10:00
Nick Brassel dea98e71b8 Revert, no work. 2023-04-03 07:46:20 +10:00
Nick Brassel ea62fa1cec Let's try that again. 2023-04-03 07:45:24 +10:00
Nick Brassel 32129ee5a2 Update qmk_cli/subcommands/console.py
Co-authored-by: Sergey Vlasov <sigprof@gmail.com>
2023-04-03 07:43:04 +10:00
Nick Brassel 6638c13c36 Take 2 2023-04-02 10:32:27 +10:00
Nick Brassel 98ab6a52f6 Attempted formatting fix. 2023-04-02 10:27:46 +10:00
Joel Challis f9d3020616 Fix docker build? (#144) 2023-03-16 23:06:24 +00:00
zvecr 1c98cf7053 Fix republish 2023-03-16 22:57:57 +00:00
Joel Challis 6b98cb311f Update to reflect latest base container (#143)
* pull base container from ghcr
* also push to ghcr
* also publish arm container
2023-03-16 22:51:14 +00:00
dependabot[bot] 8a4bf2d437 Bump docker/build-push-action from 3.3.0 to 4.0.0 (#142)
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 3.3.0 to 4.0.0.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/v3.3.0...v4.0.0)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-02-28 22:35:32 +00:00
Nick Brassel db645b7db8 Merge pull request #137 from qmk/zvecr-patch-2 2023-01-19 10:39:39 +11:00
Nick Brassel 3f4c491202 Merge pull request #138 from qmk/zvecr-patch-1 2023-01-19 10:39:23 +11:00
Nick Brassel 39d3adddff Merge pull request #141 from qmk/dependabot/github_actions/docker/build-push-action-3.3.0 2023-01-17 04:43:12 +11:00
dependabot[bot] d557058db7 Bump docker/build-push-action from 3.2.0 to 3.3.0
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 3.2.0 to 3.3.0.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/v3.2.0...v3.3.0)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-16 17:02:47 +00:00
Joel Challis 3126bdb90a Also handle clone too 2023-01-02 03:31:01 +00:00
Joel Challis d2f73683f8 Allow setup to handle empty home directories 2023-01-02 03:09:52 +00:00
Joel Challis 83978d4c68 Run qmk doctor in the correct directory 2023-01-02 02:59:51 +00:00
dependabot[bot] bb00940631 Bump docker/build-push-action from 3.1.1 to 3.2.0 (#135)
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 3.1.1 to 3.2.0.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/v3.1.1...v3.2.0)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-27 22:00:55 +00:00
dependabot[bot] 29bcd3aa01 Bump docker/login-action from 2.0.0 to 2.1.0 (#134)
Bumps [docker/login-action](https://github.com/docker/login-action) from 2.0.0 to 2.1.0.
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](https://github.com/docker/login-action/compare/v2.0.0...v2.1.0)

---
updated-dependencies:
- dependency-name: docker/login-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-27 22:00:35 +00:00
QMK Bot 42481f2db3 New release: 1.1.0 → 1.1.1 2022-08-20 13:32:16 +00:00
Nick Brassel 928d22d370 Merge pull request #133 from qmk/zvecr-patch-2 2022-08-20 23:02:28 +10:00
Nick Brassel 169e12a4c6 tabs/spaces etc. 2022-08-20 22:53:15 +10:00
Joel Challis 26ad0cd2b9 Align dependencies to develop 2022-08-20 11:52:15 +01:00
dependabot[bot] 63fc8ff722 Bump docker/build-push-action from 3.0.0 to 3.1.1 (#132) 2022-08-20 11:49:39 +01:00
Ryan bb912d3473 Revert dependency on qmk-dotty-dict (#129) 2022-07-12 11:45:34 +10:00
dependabot[bot] 7cb41c2daa Bump actions/setup-python from 3 to 4 (#130)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-07-03 10:51:43 +10:00
QMK Bot c7af299b48 New release: 1.0.0 → 1.1.0 2022-05-21 23:36:07 +00:00
Joel Challis c0698e953b Disable use of config for setup|clone|env (#128) 2022-05-20 23:53:24 +01:00
Joel Challis 54bf8328a1 Merge pull request #127 from qmk/python-requires-typo
Fix typo
2022-05-20 19:46:00 +01:00
Ryan ace9daea3e Fix typo 2022-05-20 23:51:03 +10:00
Joel Challis 255990f45b Merge pull request #122 from qmk/dependabot/github_actions/github/codeql-action-2
Bump github/codeql-action from 1 to 2
2022-05-17 21:50:40 +01:00
Joel Challis 1742e84da5 Merge pull request #125 from qmk/zvecr-patch-2
Align to current qmk_firmware develop deps
2022-05-17 21:50:31 +01:00
Joel Challis 2b4021eaa2 whitespace 2022-05-17 21:27:11 +01:00
Joel Challis 670ead38ad Install msys package for pillow? 2022-05-17 21:20:22 +01:00
Joel Challis c12c4a6e0d Align to current qmk_firmware develop deps 2022-05-17 21:09:32 +01:00
Joel Challis bd5e3b5cb4 Merge pull request #124 from qmk/dependabot/github_actions/docker/build-push-action-3.0.0
Bump docker/build-push-action from 2.10.0 to 3.0.0
2022-05-10 04:05:28 +01:00
Joel Challis 82fede52ac Merge pull request #123 from qmk/dependabot/github_actions/docker/login-action-2.0.0
Bump docker/login-action from 1.14.1 to 2.0.0
2022-05-10 04:05:19 +01:00
dependabot[bot] 76fa43cf78 Bump docker/build-push-action from 2.10.0 to 3.0.0
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 2.10.0 to 3.0.0.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Upgrade guide](https://github.com/docker/build-push-action/blob/master/UPGRADE.md)
- [Commits](https://github.com/docker/build-push-action/compare/v2.10.0...v3.0.0)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-05 17:15:16 +00:00
dependabot[bot] 7ec12a8b9d Bump docker/login-action from 1.14.1 to 2.0.0
Bumps [docker/login-action](https://github.com/docker/login-action) from 1.14.1 to 2.0.0.
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](https://github.com/docker/login-action/compare/v1.14.1...v2.0.0)

---
updated-dependencies:
- dependency-name: docker/login-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-05 17:15:12 +00:00
dependabot[bot] b714ea60c3 Bump github/codeql-action from 1 to 2
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 1 to 2.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/v1...v2)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-26 17:20:16 +00:00
Joel Challis 1797e83de8 Merge pull request #119 from Erovia/bump_jsonschema_version
Bump the 'jsonschema' version
2022-04-06 19:43:45 +01:00
Joel Challis 593ae652e6 Merge pull request #120 from qmk/dependabot/github_actions/docker/build-push-action-2.10.0
Bump docker/build-push-action from 2.9.0 to 2.10.0
2022-03-28 06:29:09 +01:00
dependabot[bot] 963818be15 Bump docker/build-push-action from 2.9.0 to 2.10.0
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 2.9.0 to 2.10.0.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/v2.9.0...v2.10.0)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-15 17:17:45 +00:00
Erovia 47b977f9b2 Bump the 'jsonschema' version
Bump the installed version of jsonschema to >=4 so we have access to the
validator of the latest meta-schema.
As we already request >=3, installations after 2021-11-30 should satisfy
the new requirements.
2022-03-13 21:45:25 +00:00
Joel Challis 8c0f655483 Merge pull request #118 from qmk/dependabot/github_actions/docker/login-action-1.14.1
Bump docker/login-action from 1.14.0 to 1.14.1
2022-03-08 21:56:23 +00:00
Joel Challis e0aacc9dc7 Merge pull request #117 from qmk/dependabot/github_actions/actions/checkout-3
Bump actions/checkout from 2.4.0 to 3
2022-03-08 21:56:17 +00:00
dependabot[bot] 24472967eb Bump docker/login-action from 1.14.0 to 1.14.1
Bumps [docker/login-action](https://github.com/docker/login-action) from 1.14.0 to 1.14.1.
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](https://github.com/docker/login-action/compare/v1.14.0...v1.14.1)

---
updated-dependencies:
- dependency-name: docker/login-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-02 17:17:16 +00:00
dependabot[bot] 1a2e43aa58 Bump actions/checkout from 2.4.0 to 3
Bumps [actions/checkout](https://github.com/actions/checkout) from 2.4.0 to 3.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v2.4.0...v3)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-02 17:17:13 +00:00
Joel Challis ffed902922 Merge pull request #115 from qmk/dependabot/github_actions/actions/setup-python-3
Bump actions/setup-python from 2.3.2 to 3
2022-02-28 19:58:09 +00:00
Joel Challis 325868514b Merge pull request #116 from qmk/dependabot/github_actions/docker/login-action-1.14.0
Bump docker/login-action from 1.13.0 to 1.14.0
2022-02-28 19:56:33 +00:00
dependabot[bot] dbfdd2dec5 Bump docker/login-action from 1.13.0 to 1.14.0
Bumps [docker/login-action](https://github.com/docker/login-action) from 1.13.0 to 1.14.0.
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](https://github.com/docker/login-action/compare/v1.13.0...v1.14.0)

---
updated-dependencies:
- dependency-name: docker/login-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-28 17:20:12 +00:00
dependabot[bot] de7f8f6b70 Bump actions/setup-python from 2.3.2 to 3
Bumps [actions/setup-python](https://github.com/actions/setup-python) from 2.3.2 to 3.
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](https://github.com/actions/setup-python/compare/v2.3.2...v3)

---
updated-dependencies:
- dependency-name: actions/setup-python
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-28 17:20:09 +00:00
Joel Challis 552fe67430 Merge pull request #114 from qmk/rebuild_docker
Add workflow to rebuild docker image
2022-02-21 11:07:00 +00:00
zvecr de28654c6d Add workflow to rebuild docker image 2022-02-20 22:00:13 +00:00
Joel Challis 02c190894a Merge pull request #112 from qmk/dependabot/github_actions/actions/setup-python-2.3.2
Bump actions/setup-python from 2.2.2 to 2.3.2
2022-02-20 20:49:38 +00:00
dependabot[bot] 7df9a61f89 Bump actions/setup-python from 2.2.2 to 2.3.2
Bumps [actions/setup-python](https://github.com/actions/setup-python) from 2.2.2 to 2.3.2.
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](https://github.com/actions/setup-python/compare/v2.2.2...v2.3.2)

---
updated-dependencies:
- dependency-name: actions/setup-python
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-20 20:22:18 +00:00
Joel Challis dad8b3c15a Merge pull request #113 from qmk/dependabot/github_actions/docker/login-action-1.13.0
Bump docker/login-action from 1.10.0 to 1.13.0
2022-02-20 20:22:06 +00:00
Joel Challis e24448ed18 Merge pull request #111 from qmk/dependabot/github_actions/docker/build-push-action-2.9.0
Bump docker/build-push-action from 2.6.1 to 2.9.0
2022-02-20 20:21:54 +00:00
Joel Challis 9befc84294 Merge pull request #102 from qmk/dependabot/github_actions/actions/checkout-2.4.0
Bump actions/checkout from 2.3.4 to 2.4.0
2022-02-20 20:21:23 +00:00
dependabot[bot] bb489e8ec2 Bump docker/login-action from 1.10.0 to 1.13.0
Bumps [docker/login-action](https://github.com/docker/login-action) from 1.10.0 to 1.13.0.
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](https://github.com/docker/login-action/compare/v1.10.0...v1.13.0)

---
updated-dependencies:
- dependency-name: docker/login-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-17 17:19:35 +00:00
Ryan f208f0228c Dependabot config: request review for Actions dependencies (#110) 2022-02-08 12:55:26 +11:00
dependabot[bot] e4e8f987e1 Bump docker/build-push-action from 2.6.1 to 2.9.0
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 2.6.1 to 2.9.0.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/v2.6.1...v2.9.0)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-01 17:14:21 +00:00
dependabot[bot] 9f74f1ca9c Bump actions/checkout from 2.3.4 to 2.4.0
Bumps [actions/checkout](https://github.com/actions/checkout) from 2.3.4 to 2.4.0.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v2.3.4...v2.4.0)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-11-03 17:13:33 +00:00
Joel Challis bb1a9e43cf Merge pull request #97 from qmk/bootloader-list-update
Update bootloader list
2021-09-23 15:53:07 +01:00
Ryan 501182017e Update bootloader list 2021-09-13 19:47:11 +10:00
QMK Bot 710dc3e951 New release: 0.4.0 → 1.0.0 2021-08-25 03:13:23 +00:00
QMK Bot 12242d94c2 New release: 0.3.5 → 0.4.0 2021-08-24 17:39:24 +00:00
Nick Brassel 19336ff9ee Merge pull request #96 from qmk/unpin_deps
Unpin dependencies
2021-08-24 16:36:44 +10:00
Zach White 8e1de74918 remove non-direct dependencies 2021-08-23 15:13:24 -07:00
Zach White 137ed60056 unpin dependencies 2021-08-23 14:59:05 -07:00
Nick Brassel d320265936 Merge pull request #93 from drashna/console_qmk_hid
Add LUFA/QMK HID Bootloader support
2021-08-18 04:24:11 +10:00
Drashna Jael're 97346a44bc Begrudgingly add lufa-ms 2021-08-17 01:27:59 -07:00
Drashna Jael're 1e0b08250d Add LUFA/QMK HID Bootloader support
And remove duplicate entry
2021-08-16 22:39:52 -07:00
QMK Bot 6a928e9322 New release: 0.3.4 → 0.3.5 2021-08-13 18:26:21 +00:00
QMK Bot 5315431058 New release: 0.3.3 → 0.3.4 2021-08-13 18:07:41 +00:00
Zach White aa11928c03 remove extraneous backticks 2021-08-12 11:38:48 -07:00
Zach White 369c3e150a document building and packages in the readme 2021-08-12 11:18:15 -07:00
Zach White c4e82e0740 only trigger fedora32 2021-08-12 10:40:51 -07:00
QMK Bot 95152b6f7f New release: 0.3.2 → 0.3.3 2021-08-12 17:27:08 +00:00
Zach White 3bd1a79bfa fix ref for trigger 2021-08-12 10:25:27 -07:00
QMK Bot 42fcfc3930 New release: 0.3.1 → 0.3.2 2021-08-12 17:22:35 +00:00
Zach White 60f2bb743d Move bumpversion config to .bumpversion.cfg
It seems that bumpversion only bumps the first match in a file,
with no way I can find to get around that. This works around the
problem so that bumpversion works in our setup.py-less world.
2021-08-12 10:18:13 -07:00
Zach White f8902bd258 fix setup.cfg version 2021-08-12 10:12:58 -07:00
QMK Bot f7125127f1 New release: 0.3.0 → 0.3.1 2021-08-12 17:05:55 +00:00
Zach White f8fe363999 Modernize the qmk_cli package (#91)
* bring our package into the future

* trigger the OS packages upon a successful build

* fix windows

* trim deps

* remove the qmk_cli module from setup
2021-08-12 09:53:28 -07:00
QMK Bot bbd667e30c New release: 0.2.2 → 0.3.0 2021-08-11 02:54:39 +00:00
dependabot[bot] 32506bf1bb Bump milc from 1.4.2 to 1.5.0 (#90)
Bumps [milc](https://github.com/clueboard/milc) from 1.4.2 to 1.5.0.
- [Release notes](https://github.com/clueboard/milc/releases)
- [Commits](https://github.com/clueboard/milc/compare/1.4.2...1.5.0)

---
updated-dependencies:
- dependency-name: milc
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-08-10 19:46:28 -07:00
Zach White 45a231af0c Add qmk console to the global cli (#84)
* add qmk console to the global cli

* lazy load hid and usb.core

* lazy load hid and usb.core
2021-08-10 11:25:00 -07:00
dependabot[bot] 1f7ad8a73e Bump bleach from 3.3.1 to 4.0.0 (#88)
Bumps [bleach](https://github.com/mozilla/bleach) from 3.3.1 to 4.0.0.
- [Release notes](https://github.com/mozilla/bleach/releases)
- [Changelog](https://github.com/mozilla/bleach/blob/main/CHANGES)
- [Commits](https://github.com/mozilla/bleach/compare/v3.3.1...v4.0.0)

---
updated-dependencies:
- dependency-name: bleach
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-08-04 11:22:09 -07:00
dependabot[bot] 2faca28631 Bump jeepney from 0.7.0 to 0.7.1 (#85)
Bumps [jeepney](https://gitlab.com/takluyver/jeepney) from 0.7.0 to 0.7.1.
- [Release notes](https://gitlab.com/takluyver/jeepney/tags)
- [Commits](https://gitlab.com/takluyver/jeepney/compare/0.7...0.7.1)

---
updated-dependencies:
- dependency-name: jeepney
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-08-04 10:25:54 -07:00
dependabot[bot] d99eed2ed0 Bump tqdm from 4.61.2 to 4.62.0 (#86)
Bumps [tqdm](https://github.com/tqdm/tqdm) from 4.61.2 to 4.62.0.
- [Release notes](https://github.com/tqdm/tqdm/releases)
- [Commits](https://github.com/tqdm/tqdm/compare/v4.61.2...v4.62.0)

---
updated-dependencies:
- dependency-name: tqdm
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-08-04 10:23:20 -07:00
dependabot[bot] a5a481e322 Bump importlib-metadata from 4.6.1 to 4.6.3 (#87)
Bumps [importlib-metadata](https://github.com/python/importlib_metadata) from 4.6.1 to 4.6.3.
- [Release notes](https://github.com/python/importlib_metadata/releases)
- [Changelog](https://github.com/python/importlib_metadata/blob/main/CHANGES.rst)
- [Commits](https://github.com/python/importlib_metadata/compare/v4.6.1...v4.6.3)

---
updated-dependencies:
- dependency-name: importlib-metadata
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-08-04 10:23:07 -07:00
dependabot[bot] 21daea7028 Bump twine from 3.4.1 to 3.4.2 (#83)
Bumps [twine](https://github.com/pypa/twine) from 3.4.1 to 3.4.2.
- [Release notes](https://github.com/pypa/twine/releases)
- [Changelog](https://github.com/pypa/twine/blob/main/docs/changelog.rst)
- [Commits](https://github.com/pypa/twine/compare/3.4.1...3.4.2)

---
updated-dependencies:
- dependency-name: twine
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-07-20 11:03:44 -07:00
QMK Bot 51e80c2f52 New release: 0.2.1 → 0.2.2 2021-07-16 20:08:42 +00:00
Zach White 567ef9637e fix the docker build 2021-07-16 13:06:44 -07:00
QMK Bot e8818c9d23 New release: 0.2.0 → 0.2.1 2021-07-16 19:30:38 +00:00
Zach White 2710813c51 Switch to installing the locally built package (#80) 2021-07-15 21:39:39 -07:00
dependabot[bot] fb69e6d50a Bump requests from 2.25.1 to 2.26.0 (#79)
Bumps [requests](https://github.com/psf/requests) from 2.25.1 to 2.26.0.
- [Release notes](https://github.com/psf/requests/releases)
- [Changelog](https://github.com/psf/requests/blob/master/HISTORY.md)
- [Commits](https://github.com/psf/requests/compare/v2.25.1...v2.26.0)

---
updated-dependencies:
- dependency-name: requests
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-07-15 21:39:10 -07:00
dependabot[bot] 135d9f63a1 Bump bleach from 3.3.0 to 3.3.1 (#81)
Bumps [bleach](https://github.com/mozilla/bleach) from 3.3.0 to 3.3.1.
- [Release notes](https://github.com/mozilla/bleach/releases)
- [Changelog](https://github.com/mozilla/bleach/blob/master/CHANGES)
- [Commits](https://github.com/mozilla/bleach/compare/v3.3.0...v3.3.1)

---
updated-dependencies:
- dependency-name: bleach
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-07-15 21:38:44 -07:00
dependabot[bot] 695cd7eb4d Bump jeepney from 0.6.0 to 0.7.0 (#78)
Bumps [jeepney](https://gitlab.com/takluyver/jeepney) from 0.6.0 to 0.7.0.
- [Release notes](https://gitlab.com/takluyver/jeepney/tags)
- [Commits](https://gitlab.com/takluyver/jeepney/compare/0.6...0.7)

---
updated-dependencies:
- dependency-name: jeepney
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-07-14 10:20:57 -07:00
QMK Bot 61ca025afd New release: 0.1.1 → 0.2.0 2021-07-11 16:30:21 +00:00
Zach White 2bd1630621 switch to the qmk-dotty-dict package (#77) 2021-07-11 09:22:22 -07:00
dependabot[bot] 34517d01b7 Bump cffi from 1.14.5 to 1.14.6 (#76)
Bumps [cffi](http://cffi.readthedocs.org) from 1.14.5 to 1.14.6.

---
updated-dependencies:
- dependency-name: cffi
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-07-10 08:21:45 -07:00
dependabot[bot] 0a4d66e13a Bump pyusb from 1.2.0 to 1.2.1 (#75)
Bumps [pyusb](https://github.com/pyusb/pyusb) from 1.2.0 to 1.2.1.
- [Release notes](https://github.com/pyusb/pyusb/releases)
- [Commits](https://github.com/pyusb/pyusb/compare/v1.2.0...v1.2.1)

---
updated-dependencies:
- dependency-name: pyusb
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-07-10 08:21:36 -07:00
dependabot[bot] fe0a3af05f Bump pkginfo from 1.7.0 to 1.7.1 (#74)
Bumps [pkginfo](https://code.launchpad.net/~tseaver/pkginfo/trunk) from 1.7.0 to 1.7.1.

---
updated-dependencies:
- dependency-name: pkginfo
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-07-10 08:21:20 -07:00
QMK Bot 4508b8548f New release: 0.1.0 → 0.1.1 2021-07-09 02:54:33 +00:00
dependabot[bot] 2ea90a0893 Bump docker/build-push-action from 2.5.0 to 2.6.1 (#73)
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 2.5.0 to 2.6.1.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/v2.5.0...v2.6.1)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-07-08 19:13:32 -07:00
Zach White 9fccc990be Add infrastructure to build and push docker containers (#64)
* add infrastructure to build and push docker containers

* make it part of the deploy workflow
2021-07-07 22:54:34 -07:00
Zach White 6d99eacdf8 switch windows back to the old method 2021-07-07 21:29:22 -07:00
Zach White dbd731585a switch the pip command 2021-07-07 21:19:59 -07:00
Zach White 9d480bd287 attempt to fix windows 2021-07-07 21:12:29 -07:00
Zach White 709f416e52 switch the gh-actions to use ci_tests 2021-07-07 20:14:04 -07:00
Zach White bcdac9a80e add a basic ci test to make testing easier 2021-07-07 20:00:39 -07:00
dependabot[bot] 4772e68828 Bump tqdm from 4.61.1 to 4.61.2 (#72)
Bumps [tqdm](https://github.com/tqdm/tqdm) from 4.61.1 to 4.61.2.
- [Release notes](https://github.com/tqdm/tqdm/releases)
- [Commits](https://github.com/tqdm/tqdm/compare/v4.61.1...v4.61.2)

---
updated-dependencies:
- dependency-name: tqdm
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-07-07 19:29:43 -07:00
dependabot[bot] 24741c7d2b Bump pyrsistent from 0.17.3 to 0.18.0 (#66)
Bumps [pyrsistent](https://github.com/tobgu/pyrsistent) from 0.17.3 to 0.18.0.
- [Release notes](https://github.com/tobgu/pyrsistent/releases)
- [Changelog](https://github.com/tobgu/pyrsistent/blob/master/CHANGES.txt)
- [Commits](https://github.com/tobgu/pyrsistent/compare/v0.17.3...v0.18.0)

---
updated-dependencies:
- dependency-name: pyrsistent
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-07-07 19:28:51 -07:00
dependabot[bot] b756421528 Bump importlib-metadata from 4.5.0 to 4.6.1 (#68)
Bumps [importlib-metadata](https://github.com/python/importlib_metadata) from 4.5.0 to 4.6.1.
- [Release notes](https://github.com/python/importlib_metadata/releases)
- [Changelog](https://github.com/python/importlib_metadata/blob/main/CHANGES.rst)
- [Commits](https://github.com/python/importlib_metadata/compare/v4.5.0...v4.6.1)

---
updated-dependencies:
- dependency-name: importlib-metadata
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-07-07 19:28:21 -07:00
dependabot[bot] 3d96bcdc14 Bump pyusb from 1.1.1 to 1.2.0 (#69)
Bumps [pyusb](https://github.com/pyusb/pyusb) from 1.1.1 to 1.2.0.
- [Release notes](https://github.com/pyusb/pyusb/releases)
- [Commits](https://github.com/pyusb/pyusb/compare/v1.1.1...v1.2.0)

---
updated-dependencies:
- dependency-name: pyusb
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-07-07 19:27:50 -07:00
dependabot[bot] 6e6b6bcde6 Bump packaging from 20.9 to 21.0 (#70)
Bumps [packaging](https://github.com/pypa/packaging) from 20.9 to 21.0.
- [Release notes](https://github.com/pypa/packaging/releases)
- [Changelog](https://github.com/pypa/packaging/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pypa/packaging/compare/20.9...21.0)

---
updated-dependencies:
- dependency-name: packaging
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-07-07 19:27:24 -07:00
dependabot[bot] 1df06eed72 Bump zipp from 3.4.1 to 3.5.0 (#71)
Bumps [zipp](https://github.com/jaraco/zipp) from 3.4.1 to 3.5.0.
- [Release notes](https://github.com/jaraco/zipp/releases)
- [Changelog](https://github.com/jaraco/zipp/blob/main/CHANGES.rst)
- [Commits](https://github.com/jaraco/zipp/compare/v3.4.1...v3.5.0)

---
updated-dependencies:
- dependency-name: zipp
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-07-07 19:27:04 -07:00
QMK Bot 60a56b6976 New release: 0.0.52 → 0.1.0 2021-06-26 16:31:53 +00:00
dependabot[bot] 1e3605feb3 Bump actions/setup-python from 1 to 2.2.2 (#58)
Bumps [actions/setup-python](https://github.com/actions/setup-python) from 1 to 2.2.2.
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](https://github.com/actions/setup-python/compare/v1...v2.2.2)

---
updated-dependencies:
- dependency-name: actions/setup-python
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-06-26 08:34:56 -07:00
dependabot[bot] 48ddcefea1 Bump actions/checkout from 1 to 2.3.4 (#57)
Bumps [actions/checkout](https://github.com/actions/checkout) from 1 to 2.3.4.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v1...v2.3.4)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-06-26 08:34:43 -07:00
Zach White 2f6f38cc33 Ensure that qmk doctor can be answered on windows (#63) 2021-06-25 18:55:51 -07:00
dependabot[bot] c73ae7e97c Bump urllib3 from 1.26.5 to 1.26.6 (#62)
Bumps [urllib3](https://github.com/urllib3/urllib3) from 1.26.5 to 1.26.6.
- [Release notes](https://github.com/urllib3/urllib3/releases)
- [Changelog](https://github.com/urllib3/urllib3/blob/1.26.6/CHANGES.rst)
- [Commits](https://github.com/urllib3/urllib3/compare/1.26.5...1.26.6)

---
updated-dependencies:
- dependency-name: urllib3
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-06-25 15:23:58 -07:00
Zach White 0475193870 Create SECURITY.md 2021-06-23 20:27:04 -07:00
Zach White 8d9b3b2880 pin versions and use dependabot to update them (#56) 2021-06-23 19:28:31 -07:00
Zach White 0dbe3dc448 Setup codeql analysis 2021-06-23 10:29:23 -07:00
QMK Bot c41fd5e940 New release: 0.0.51 → 0.0.52 2021-06-22 05:21:24 +00:00
Zach White b70736a876 add vscode settings 2021-06-21 22:14:55 -07:00
Zach White 69b3b890d2 check for __init__ instead of doctor 2021-06-21 22:14:38 -07:00
QMK Bot 8b30a9766d New release: 0.0.50 → 0.0.51 2021-05-27 02:16:09 +00:00
Zach White 982349a450 move the yesno import to after the set_metadata call 2021-05-26 19:00:16 -07:00
Zach White 4d161c9ec4 fix qmk config 2021-05-26 17:55:15 -07:00
QMK Bot 047eb00594 New release: 0.0.49 → 0.0.50 2021-05-26 17:13:15 +00:00
Ryan 558251860a Updates for milc 1.4.0 (#52)
* Updates for milc 1.4.0

* Add halo dependency

* Just set version for now; remove halo as milc 1.4.1 should pull that in

* Bump milc

* Remove appdirs, argcomplete and colorama as they are also pulled in by MILC
2021-05-26 10:07:13 -07:00
QMK Bot b685fe5d3f New release: 0.0.48 → 0.0.49 2021-05-25 06:16:01 +00:00
Zach White e447fb4252 mark user.qmk_home as a config_file option (#53) 2021-05-24 23:15:13 -07:00
Zach White 066a865084 remove the release script 2021-05-10 12:42:11 -07:00
QMK Bot a1276f8d58 New release: 0.0.47 → 0.0.48 2021-05-10 19:40:17 +00:00
Zach White 3555e34ae9 New release: 0.0.46 → 0.0.47 2021-05-10 12:39:08 -07:00
Zach White b36cf144e3 Pass color and unicode settings down to qmk doctor
fixes #50
2021-05-10 12:28:37 -07:00
Zach White fb05b69adc update README 2021-05-10 12:24:05 -07:00
Zach White 4283c258d9 remove the module checking code in favor of qmk_firmware doing that directly 2021-05-10 12:22:44 -07:00
Zach White b5e8aa4cac New release: 0.0.45 → 0.0.46 2021-05-08 21:04:06 -07:00
Zach White 1c6d81fc3b add hid and pyusb to the requirements 2021-05-08 21:03:31 -07:00
Erovia 0ffae74377 Merge pull request #49 from zvecr/env_command 2021-05-08 13:00:46 +02:00
zvecr cbe3ad0248 Expose is_qmk_firmware status 2021-04-08 23:41:12 +01:00
zvecr 97689b53d7 Add cli.config.general 2021-04-05 21:29:56 +01:00
zvecr 054e071787 Add env subcommand 2021-04-05 21:01:29 +01:00
QMK Bot 78e0fda2f0 New release: 0.0.44 → 0.0.45 2021-03-28 23:43:02 +00:00
Zach White 9c6123483b housekeeping 2021-03-28 16:23:15 -07:00
QMK Bot e851c8fcb5 New release: 0.0.43 → 0.0.44 2021-03-28 01:51:59 +00:00
QMK Bot 92168e1ef0 New release: 0.0.42 → 0.0.43 2021-03-28 01:41:34 +00:00
Zach White fd744ac24c Setup an action to publish a release 2021-03-27 18:38:47 -07:00
Zach White 840c791cc8 don't use sys.executable when running qmk doctor 2021-03-27 17:02:04 -07:00
Zach White 8f5b8e83c0 New release: 0.0.41 → 0.0.42 2021-03-27 13:03:22 -07:00
Zach White 1da98510d3 make the qmk_firmware check more robust 2021-03-27 11:34:36 -07:00
34 changed files with 2112 additions and 408 deletions
+12
View File
@@ -0,0 +1,12 @@
[bumpversion]
current_version = 1.2.0
commit = True
tag = True
tag_name = {new_version}
message = New release: {current_version} → {new_version}
[bumpversion:file:.bumpversion.cfg]
[bumpversion:file:qmk_cli/__init__.py]
[bumpversion:file:pyproject.toml]
+17
View File
@@ -0,0 +1,17 @@
# Please see the documentation for all configuration options:
# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
version: 2
updates:
- package-ecosystem: "github-actions" # See documentation for possible values
directory: "/"
schedule:
interval: "daily"
reviewers:
- "qmk/collaborators"
- package-ecosystem: "pip" # See documentation for possible values
directory: "/" # Location of package manifests
schedule:
interval: "daily"
reviewers:
- "qmk/collaborators"
+41
View File
@@ -0,0 +1,41 @@
name: CLI Lint
permissions:
contents: read
on:
push:
branches:
- master
pull_request:
paths:
- 'qmk_cli/**'
- 'pyproject.toml'
- '.github/workflows/cli_lint.yml'
jobs:
lint:
runs-on: ubuntu-slim
steps:
- uses: actions/setup-python@v6
with:
python-version: '3.9'
- name: Activate virtualenv
shell: bash
run: |
python -m venv .ci_venv
source .ci_venv/bin/activate
echo PATH=$PATH >> $GITHUB_ENV
- uses: actions/checkout@v7
- name: Install dependencies
run: python -m pip install --group dev
- name: Run lint
run: ruff check --no-cache --output-format=github
- name: Run format
run: yapf -r --diff qmk_cli test
+86 -32
View File
@@ -7,65 +7,119 @@ on:
pull_request:
jobs:
test_cli_base_container:
runs-on: ubuntu-latest
container: ghcr.io/qmk/qmk_base_container
steps:
- uses: actions/checkout@v7
- name: Install dependencies
run: apt-get update && apt-get install -y python3-venv
- name: Run unit test
shell: bash
run: |
python3 -m venv .ci_venv
source .ci_venv/bin/activate
python3 -m pip install -r requirements.txt
python3 -m pip install --group dev
pytest
- name: Run ci_tests
run: ./ci_tests
test_cli_linux_macos:
needs: test_cli_base_container
runs-on: ${{ matrix.os }}
env:
QMK_HOME: ~/qmk_firmware
strategy:
matrix:
os: [macos-latest, ubuntu-latest]
python-version: [3.7, 3.8, 3.9]
python-version: ['3.9', '3.10', '3.11', '3.12', '3.13', '3.14']
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v7
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v1
uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python-version }}
- name: Install Python dependencies
run: |
python3 -m pip install wheel
echo "$HOME/.local/bin" >> $GITHUB_PATH
- name: Install QMK CLI from source
run: |
python3 -m pip install -r requirements.txt
python3 setup.py sdist bdist_wheel
cd ..
python3 -m pip install --force-reinstall --no-index --no-deps --prefix=~/.local --find-links qmk_cli/dist qmk
- name: Run qmk setup -y
run: qmk setup -y
- name: Run ci_tests
run: ./ci_tests
test_cli_win:
needs: test_cli_base_container
runs-on: windows-latest
env:
QMK_HOME: $HOME/qmk_firmware
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v7
- name: (MSYS2) Setup and install dependencies
uses: msys2/setup-msys2@v2
with:
update: true
install: git mingw-w64-x86_64-toolchain mingw-w64-x86_64-python-pip
install: git mingw-w64-x86_64-toolchain mingw-w64-x86_64-python-pip mingw-w64-x86_64-python-build mingw-w64-x86_64-python-pillow mingw-w64-x86_64-rust mingw-w64-x86_64-python-halo mingw-w64-x86_64-python-nh3 mingw-w64-x86_64-python-rpds-py mingw-w64-x86_64-python-ruff
# Upgrade pip due to msys packaging + pypa/build/pull/736 issues
- name: (MSYS2) Install Python dependencies
shell: msys2 {0}
run: |
python3 -m pip install wheel
python3 -m pip install --break-system-packages --force-reinstall --upgrade pip
- name: (MSYS2) Install QMK CLI from source
- name: Run ci_tests
shell: msys2 {0}
run: ./ci_tests
test_docker_container:
needs: test_cli_base_container
runs-on: ubuntu-latest
env:
TEST_TAG: qmkfm/qmk_cli:test
steps:
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: '3.9'
- name: Set up QEMU
uses: docker/setup-qemu-action@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4
- uses: actions/checkout@v7
- name: Install dependencies
run: |
python3 -m pip install -r requirements.txt
python3 setup.py sdist bdist_wheel
cd ..
python3 -m pip install --force-reinstall --no-index --no-deps --find-links qmk_cli/dist qmk
python3 -m pip install --upgrade pip
pip install setuptools wheel
pip install --group dev
- name: (MSYS2) Run qmk setup -y
shell: msys2 {0}
run: qmk setup -y
- name: Build Python
run: |
python3 -m build
- name: Build Test Container
uses: docker/build-push-action@v7
with:
context: .
load: true
tags: ${{ env.TEST_TAG }}
- name: Test
run: |
docker run --rm -v ${{ github.workspace }}:/qmk_cli -w /qmk_cli ${{ env.TEST_TAG }} /qmk_cli/ci_tests
- name: Build All Containers
uses: docker/build-push-action@v7
with:
context: .
target: full
platforms: linux/amd64,linux/arm64
+71
View File
@@ -0,0 +1,71 @@
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL"
on:
push:
branches: [ master ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ master ]
schedule:
- cron: '22 18 * * 0'
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
language: [ 'python' ]
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ]
# Learn more:
# https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed
steps:
- name: Checkout repository
uses: actions/checkout@v7
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v4
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# queries: ./path/to/local/query, your-org/your-repo/queries@main
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v4
# ️ Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
# and modify them (or add more) to build your code if your project
# uses a compiled language
#- run: |
# make bootstrap
# make release
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v4
+74
View File
@@ -0,0 +1,74 @@
name: Rebuild Docker Image
on:
workflow_dispatch:
jobs:
redeploy:
runs-on: ubuntu-latest
steps:
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: '3.9'
- name: Set up QEMU
uses: docker/setup-qemu-action@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4
- uses: actions/checkout@v7
with:
fetch-depth: 0
- name: Get Previous tag
id: previoustag
uses: "WyriHaximus/github-action-get-previous-tag@v2"
- name: Download previous artifact
run: |
pip download -d "${GITHUB_WORKSPACE}/dist" qmk=="${{ steps.previoustag.outputs.tag }}"
- name: Login to GitHub Container Registry
uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Log in to Docker Hub
uses: docker/login-action@v4
with:
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}
- name: Build and Push slim to Docker Hub
uses: docker/build-push-action@v7
with:
context: .
push: true
target: slim
platforms: linux/amd64,linux/arm64
tags: |
ghcr.io/qmk/qmk_cli:slim
qmkfm/qmk_cli:slim
ghcr.io/qmk/qmk_cli:${{ steps.previoustag.outputs.tag }}-slim
qmkfm/qmk_cli:${{ steps.previoustag.outputs.tag }}-slim
- name: Build and Push full to Docker Hub
uses: docker/build-push-action@v7
with:
context: .
push: true
target: full
platforms: linux/amd64,linux/arm64
tags: |
ghcr.io/qmk/qmk_cli:latest
qmkfm/qmk_cli:latest
ghcr.io/qmk/qmk_cli:${{ github.sha }}
qmkfm/qmk_cli:${{ github.sha }}
ghcr.io/qmk/qmk_cli:${{ steps.previoustag.outputs.tag }}
qmkfm/qmk_cli:${{ steps.previoustag.outputs.tag }}
+101
View File
@@ -0,0 +1,101 @@
# This workflow will upload a Python Package using Twine when a release is created
# For more information see: https://help.github.com/en/actions/language-and-framework-guides/using-python-with-github-actions#publishing-to-package-registries
name: Upload Python Package
on:
workflow_dispatch:
inputs:
version_part:
description: 'Which part of the version to increment (patch, minor, major)'
required: true
default: 'patch'
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: '3.9'
- name: Set up QEMU
uses: docker/setup-qemu-action@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4
- uses: actions/checkout@v7
- name: Install dependencies
run: |
python3 -m pip install --upgrade pip
pip install setuptools wheel
pip install --group dev
- name: Bump version
run: |
git config --local user.email "hello@qmk.fm"
git config --local user.name "QMK Bot"
bumpversion --dry-run --list ${{ github.event.inputs.version_part }} | grep new_version= | sed "s/new_version/NEW_CLI_VERSION/" >> "$GITHUB_ENV"
bumpversion ${{ github.event.inputs.version_part }}
- name: Push changes
uses: ad-m/github-push-action@master
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
branch: master
tags: true
- name: Build and publish
env:
TWINE_USERNAME: __token__
TWINE_PASSWORD: ${{ secrets.PYPI_APITOKEN }}
run: |
python3 -m build
twine upload dist/*
- name: Login to GitHub Container Registry
uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Log in to Docker Hub
uses: docker/login-action@v4
with:
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}
- name: Build and Push slim to Docker Hub
uses: docker/build-push-action@v7
with:
context: .
push: true
target: slim
platforms: linux/amd64,linux/arm64
tags: |
ghcr.io/qmk/qmk_cli:slim
qmkfm/qmk_cli:slim
ghcr.io/qmk/qmk_cli:${{ env.NEW_CLI_VERSION }}-slim
qmkfm/qmk_cli:${{ env.NEW_CLI_VERSION }}-slim
- name: Build and Push full to Docker Hub
uses: docker/build-push-action@v7
with:
context: .
push: true
target: full
platforms: linux/amd64,linux/arm64
tags: |
ghcr.io/qmk/qmk_cli:latest
qmkfm/qmk_cli:latest
ghcr.io/qmk/qmk_cli:${{ github.sha }}
qmkfm/qmk_cli:${{ github.sha }}
ghcr.io/qmk/qmk_cli:${{ env.NEW_CLI_VERSION }}
qmkfm/qmk_cli:${{ env.NEW_CLI_VERSION }}
+3
View File
@@ -0,0 +1,3 @@
{
"python.formatting.provider": "yapf"
}
+46
View File
@@ -0,0 +1,46 @@
FROM ghcr.io/qmk/qmk_base_container:latest AS builder
# Copy package in
ADD dist /tmp/dist
# Install QMK CLI via bootstrap script
RUN mkdir -p /opt/uv/bin \
&& export UV_PYTHON_INSTALL_DIR=/opt/uv/bin \
&& /bin/bash -c "curl -fsSL https://install.qmk.fm | sh -s -- --confirm --uv-install-dir=/usr/local/bin --uv-tool-dir=/opt/uv/tools --qmk-distrib-dir=/opt/qmk"
# Do the equivalent of entering the virtual environment
ENV PATH=/opt/qmk/bin:/opt/uv/tools/qmk/bin:/usr/local/bin:$PATH \
VIRTUAL_ENV=/opt/uv/tools/qmk
# Install python packages
RUN python3 -m pip uninstall -y qmk || true
RUN python3 -m pip install --upgrade pip setuptools wheel nose2 && \
python3 -m pip install /tmp/dist/qmk-*.whl
# Allow the uv-installed python to be usable by others
RUN chmod -R go=u,go-w /opt/uv /opt/qmk
# 2nd stage so we don't have /tmp/dist in the final image
FROM ghcr.io/qmk/qmk_base_container:latest AS slim
COPY --from=builder /opt/uv /opt/uv
# Do the equivalent of entering the virtual environment
ENV PATH=/opt/uv/tools/qmk/bin:$PATH \
VIRTUAL_ENV=/opt/uv/tools/qmk \
QMK_HOME=/qmk_firmware \
QMK_USERSPACE=/qmk_userspace
# 2nd stage so we don't have /tmp/dist in the final image
FROM ghcr.io/qmk/qmk_base_container:latest AS full
COPY --from=builder /opt/uv /opt/uv
COPY --from=builder /opt/qmk /opt/qmk
# Do the equivalent of entering the virtual environment
ENV PATH=/opt/qmk/bin:/opt/uv/tools/qmk/bin:$PATH \
VIRTUAL_ENV=/opt/uv/tools/qmk \
QMK_DISTRIB_DIR=/opt/qmk \
QMK_HOME=/qmk_firmware \
QMK_USERSPACE=/qmk_userspace
+47 -12
View File
@@ -1,22 +1,57 @@
# QMK CLI
[![CLI Setup](https://github.com/qmk/qmk_cli/workflows/CLI%20Setup/badge.svg)](https://github.com/qmk/qmk_cli/actions?query=workflow%3A%22CLI+Setup%22)
A program to help users work with [QMK Firmware](https://qmk.fm/).
# Features
> A program to help users work with [QMK Firmware](https://qmk.fm/).
[![Latest Release](https://img.shields.io/github/v/tag/qmk/qmk_cli?color=3D87CE&label=Latest&sort=semver&style=for-the-badge)](https://github.com/qmk/qmk_cli/tags)
[![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/qmk/qmk_cli/cli_setup.yml?logo=github&style=for-the-badge)](https://github.com/qmk/qmk_cli/actions?query=workflow%3ACLI+branch%3Amaster)
[![Discord](https://img.shields.io/discord/440868230475677696.svg?logo=discord&logoColor=white&color=7289DA&style=for-the-badge)](https://discord.gg/qmk)
## Features
* Interact with your qmk_firmware tree from any location
* Use `qmk clone` to pull down anyone's `qmk_firmware` fork
* Setup your build environment with `qmk setup`
* Use `qmk console` to get debugging information from your keyboard(s)
* Check that your environment is correctly setup with `qmk doctor`
* Dispatches to `qmk_firmware/bin/qmk` for additional functionality:
* `qmk compile-json`
* More to come
* Integrates with qmk_firmware for additional functionality:
* `qmk compile`
* `qmk info`
* `qmk flash`
* `qmk lint`
* ...and many more!
# Quickstart
## Quickstart
Follow our [documentation to get started](https://docs.qmk.fm/newbs_getting_started).
## Packages
We provide "install and go" packages for many Operating Systems.
### macOS
Using [Homebrew](https://brew.sh):
brew install qmk/qmk/qmk
### Windows
Download our custom MSYS2 installer here: https://msys.qmk.fm/
## Building
We follow PEP517, you can install using [build](https://pypi.org/project/build/):
Setup:
python3 -m pip install --group dev
Build:
python3 -m build
You can read more about working with PEP517 packages in the [Python Packaging User Guide](https://packaging.python.org/guides/distributing-packages-using-setuptools/#packaging-your-project).
## Documentation
Full documentation: <https://docs.qmk.fm/#/tutorial>
Basic steps:
* `python3 -m pip install qmk`
* `qmk setup`
+14
View File
@@ -0,0 +1,14 @@
# Security Policy
## Supported Versions
Use this section to tell people about which versions of your project are
currently being supported with security updates.
| Version | Supported |
| ------- | ------------------ |
| 0.0.x | :white_check_mark: |
## Reporting a Vulnerability
* [Open an Issue](https://github.com/qmk/qmk_cli/issues/new?assignees=&labels=bug&template=bug_report.md&title=%5BBug%5D+)
Executable
+25
View File
@@ -0,0 +1,25 @@
#!/usr/bin/env bash
set -e
#set -x
TMPDIR=$(mktemp -d)
trap 'rm -rf "$TMPDIR"' EXIT
CI_VENV="$TMPDIR/.ci_venv"
# Avoid issues with building pillow as we install mingw-w64-x86_64-python-pillow
if [[ "$(uname -s)" =~ ^MINGW64_NT.* ]]; then
CI_VENV_ARGS="--system-site-packages"
fi
python3 -m venv $CI_VENV_ARGS $CI_VENV
source $CI_VENV/bin/activate
# Install dependencies
python3 -m pip install -U pip wheel
python3 -m pip install .
python3 -m pip install --group dev
pytest -vv -m system --qmk=real
+146
View File
@@ -0,0 +1,146 @@
[build-system]
requires = ["setuptools>=82.0.1"]
build-backend = "setuptools.build_meta"
[project]
name = "qmk"
version = "1.2.0"
license = "MIT"
readme = "README.md"
authors = [{name = "skullydazed", email = "skullydazed@gmail.com"}]
description = "A program to help users work with QMK Firmware."
classifiers = [
"Development Status :: 5 - Production/Stable",
"Environment :: Console",
"Intended Audience :: Developers",
"Intended Audience :: System Administrators",
"Intended Audience :: End Users/Desktop",
"Natural Language :: English",
"Programming Language :: Python :: 3 :: Only",
"Topic :: Scientific/Engineering",
"Topic :: Software Development",
"Topic :: Utilities",
]
requires-python = ">=3.9"
dependencies = [
"hid",
"milc>=1.9.0",
"platformdirs",
"pyusb",
# qmk_firmware packages
"dotty-dict",
"hjson",
"jsonschema>=4",
"pillow",
"pygments",
"pyserial",
]
[dependency-groups]
dev = [
"build",
"bumpversion",
"pytest",
"ruff",
"twine",
"yapf",
]
[project.urls]
"Bug Tracker" = "https://github.com/qmk/qmk_cli/issues"
Documentation = "https://docs.qmk.fm/cli"
Homepage = "https://qmk.fm/"
Source = "https://github.com/qmk/qmk_cli/"
[project.scripts]
qmk = "qmk_cli.script_qmk:main"
[tool.setuptools]
include-package-data = false
[tool.setuptools.packages]
find = {namespaces = false}
[tool.ruff]
target-version = "py39"
include = [
"qmk_cli/**/*.py",
"test/**/*.py",
]
[tool.ruff.lint]
select = ["E", "F", "B", "N", "W", "COM", "C901", "PGH004"]
ignore = [
"E501", # QMK is ok with long lines.
"E231", # Conflicts with our yapf config
]
[tool.ruff.lint.mccabe]
max-complexity = 14 # Let's slowly crank this down
[tool.yapfignore]
ignore_patterns = [
".direnv/**/*",
".env/**/*",
]
[tool.yapf]
align_closing_bracket_with_visual_indent = true
allow_multiline_dictionary_keys = false
allow_multiline_lambdas = false
allow_split_before_default_or_named_assigns = true
allow_split_before_dict_value = true
arithmetic_precedence_indication = true
blank_lines_around_top_level_definition = 2
blank_line_before_class_docstring = false
blank_line_before_module_docstring = false
blank_line_before_nested_class_or_def = false
coalesce_brackets = true
column_limit = 256
continuation_align_style = "SPACE"
continuation_indent_width = 4
dedent_closing_brackets = true
disable_ending_comma_heuristic = false
each_dict_entry_on_separate_line = true
i18n_comment = ""
i18n_function_call = ""
indent_blank_lines = false
indent_dictionary_value = true
indent_width = 4
join_multiple_lines = false
no_spaces_around_selected_binary_operators = ""
spaces_around_default_or_named_assign = false
spaces_around_power_operator = false
spaces_before_comment = 2
space_between_ending_comma_and_closing_bracket = false
split_all_comma_separated_values = false
split_arguments_when_comma_terminated = true
split_before_arithmetic_operator = false
split_before_bitwise_operator = true
split_before_closing_bracket = true
split_before_dict_set_generator = true
split_before_dot = false
split_before_expression_after_opening_paren = false
split_before_first_argument = false
split_before_logical_operator = false
split_before_named_assigns = true
split_complex_comprehension = true
split_penalty_after_opening_bracket = 300
split_penalty_after_unary_operator = 10000
split_penalty_arithmetic_operator = 300
split_penalty_before_if_expr = 0
split_penalty_bitwise_operator = 300
split_penalty_comprehension = 80
split_penalty_excess_character = 7000
split_penalty_for_added_line_split = 30
split_penalty_import_names = 0
split_penalty_logical_operator = 300
use_tabs = false
[tool.pytest.ini_options]
markers = [
"integration",
"system",
]
addopts = "-m 'not (integration or system)'"
+1
View File
@@ -2,4 +2,5 @@
"""Wrapper to call the qmk cli script entrypoint.
"""
import qmk_cli.script_qmk
qmk_cli.script_qmk.main()
+1 -1
View File
@@ -1,3 +1,3 @@
"""A program to help you work with qmk_firmware."""
__version__ = '0.0.41'
__version__ = '1.2.0'
+59 -15
View File
@@ -1,24 +1,24 @@
"""Helpers for working with git.
"""
"""Helpers for working with git."""
import subprocess
from .helpers import rmtree
from milc import cli
default_repo = 'qmk_firmware'
default_fork = 'qmk/' + default_repo
default_branch = 'master'
DEFAULT_UPSTREAM = 'https://github.com/qmk/qmk_firmware'
def git_clone(url, destination, branch):
def git_clone(destination, url, branch):
"""Add the qmk/qmk_firmware upstream to a qmk_firmware clone."""
git_clone = [
'git',
'clone',
'--recurse-submodules',
'--branch=' + branch,
f'--branch={branch}',
url,
str(destination),
]
cli.log.debug('Git clone command: %s', git_clone)
cli.log.debug(f'Git clone command: {git_clone}')
try:
with subprocess.Popen(git_clone, stderr=subprocess.STDOUT, stdout=subprocess.PIPE, bufsize=1, universal_newlines=True, encoding='utf-8') as p:
@@ -28,13 +28,57 @@ def git_clone(url, destination, branch):
except Exception as e:
git_cmd = ' '.join([s.replace(' ', r'\ ') for s in git_clone])
cli.log.error("Could not run '%s': %s: %s", git_cmd, e.__class__.__name__, e)
cli.log.error(f"Could not run '{git_cmd}': {e.__class__.__name__}:{e}")
return False
if p.returncode == 0:
cli.log.info('Successfully cloned %s to %s!', url, destination)
return True
else:
cli.log.error('git clone exited %d', p.returncode)
if p.returncode != 0:
cli.log.error(f'git clone exited {p.returncode}')
return False
cli.log.info(f'Successfully cloned {url} to {destination}!')
return True
def git_set_upstream(destination):
"""Add the qmk/qmk_firmware upstream to a qmk_firmware clone."""
git_remote = [
'git',
'-C',
str(destination),
'remote',
'add',
'upstream',
DEFAULT_UPSTREAM,
]
cli.log.debug(f'Git remote command: {git_remote}')
try:
with subprocess.Popen(git_remote, stderr=subprocess.STDOUT, stdout=subprocess.PIPE, bufsize=1, universal_newlines=True, encoding='utf-8') as p:
for line in p.stdout:
print(line, end='')
except Exception as e:
git_cmd = ' '.join([s.replace(' ', r'\ ') for s in git_remote])
cli.log.error(f"Could not run '{git_cmd}': {e.__class__.__name__}:{e}")
return False
if p.returncode != 0:
cli.log.error(f'git remote add exited {p.returncode}')
return False
cli.log.info(f'Added {DEFAULT_UPSTREAM} as remote upstream.')
return True
def git_clone_fork(destination, baseurl, fork, branch, force=False):
"""Clone fork and configure upstream."""
url = '/'.join((baseurl, fork))
if force:
rmtree(destination)
if not git_clone(destination, url, branch):
return False
return git_set_upstream(destination)
+83 -47
View File
@@ -1,68 +1,59 @@
"""Useful helper functions.
"""
import os
import sys
import stat
import json
import shutil
from functools import lru_cache
from importlib.util import find_spec
from pathlib import Path
from milc import cli
def broken_module_imports():
"""Make sure we can import all the python modules.
def AbsPath(arg): # noqa: N802
"""Resolve relative paths to the original working directory.
"""
broken_modules = find_broken_requirements('requirements.txt')
broken_dev_modules = find_broken_requirements('requirements-dev.txt') if cli.config.user.developer else []
to_return = [False, False]
arg = Path(arg)
if not arg.is_absolute():
return (Path(os.environ['ORIG_CWD']) / arg).absolute()
if broken_modules:
to_return[0] = True
if broken_dev_modules:
to_return[1] = True
for module in broken_modules + broken_dev_modules:
print('Could not find module %s!' % module)
return to_return
return arg
def find_broken_requirements(requirements):
""" Check if the modules in the given requirements.txt are available.
def rmtree(path):
"""Safe version of shutil.rmtree which handles errors on Windows where some of the files have their read-only bit set."""
def remove_readonly(func, path, _):
"""Clear the readonly bit and reattempt the removal."""
os.chmod(path, stat.S_IWRITE)
func(path)
Args:
if sys.version_info >= (3, 12):
# See https://docs.python.org/3.12/whatsnew/3.12.html#shutil
return shutil.rmtree(path, onexc=remove_readonly)
else:
return shutil.rmtree(path, onerror=remove_readonly)
requirements
The path to a requirements.txt file
Returns a list of modules that couldn't be imported
def is_qmk_firmware(qmk_firmware):
"""Returns True if the given Path() is a qmk_firmware clone.
"""
with Path(requirements).open() as fd:
broken_modules = []
paths = [
qmk_firmware,
qmk_firmware / 'quantum',
qmk_firmware / 'requirements.txt',
qmk_firmware / 'requirements-dev.txt',
qmk_firmware / 'lib/python/qmk/cli/__init__.py',
]
for line in fd.readlines():
line = line.strip().replace('<', '=').replace('>', '=')
for path in paths:
if not path.exists():
return False
if len(line) == 0 or line[0] == '#' or line.startswith('-r'):
continue
if '#' in line:
line = line.split('#')[0]
module_name = line.split('=')[0] if '=' in line else line
module_import_name = module_name.replace('-', '_')
# Not every module is importable by its own name.
if module_name == "pep8-naming":
module_import_name = "pep8ext_naming"
if not find_spec(module_import_name):
broken_modules.append(module_name)
return broken_modules
return True
@lru_cache(maxsize=2)
@lru_cache(maxsize=1)
def find_qmk_firmware():
"""Look for qmk_firmware in the usual places.
@@ -83,14 +74,59 @@ def find_qmk_firmware():
return Path.home() / 'qmk_firmware'
@lru_cache(maxsize=1)
def in_qmk_firmware():
"""Returns the path to the qmk_firmware we are currently in, or None if we are not inside qmk_firmware.
"""
cur_dir = Path.cwd()
while len(cur_dir.parents) > 0:
found_lib = cur_dir / 'lib/python/qmk/cli/__init__.py'
found_quantum = cur_dir / 'quantum'
if found_lib.is_file() and found_quantum.is_dir():
if is_qmk_firmware(cur_dir):
return cur_dir
# Move up a directory before the next iteration
cur_dir = cur_dir / '..'
cur_dir = cur_dir.resolve()
def is_qmk_userspace(qmk_userspace):
"""Returns True if the given Path() is a qmk_userspace clone.
"""
path = qmk_userspace / 'qmk.json'
if not path.exists():
return False
try:
return 'userspace_version' in json.loads(path.read_text(encoding="UTF-8"))
except json.decoder.JSONDecodeError:
return False
@lru_cache(maxsize=1)
def find_qmk_userspace():
"""Look for qmk_userspace in the usual places.
"""
if in_qmk_userspace():
return in_qmk_userspace()
if 'QMK_USERSPACE' in os.environ:
path = Path(os.environ['QMK_USERSPACE']).expanduser()
if path.exists():
return path.resolve()
return path
if cli.config.user.overlay_dir:
return Path(cli.config.user.overlay_dir).expanduser().resolve()
return Path.home() / 'qmk_userspace'
@lru_cache(maxsize=1)
def in_qmk_userspace():
"""Returns the path to the qmk_userspace we are currently in, or None if we are not inside qmk_userspace.
"""
cur_dir = Path.cwd()
while len(cur_dir.parents) > 0:
if is_qmk_userspace(cur_dir):
return cur_dir
# Move up a directory before the next iteration
+40 -44
View File
@@ -4,6 +4,7 @@
This program can be run from anywhere, with or without a qmk_firmware repository. If a qmk_firmware repository can be located we will use that to augment our available subcommands.
"""
import os
from pathlib import Path
import shlex
import subprocess
import sys
@@ -11,13 +12,39 @@ from platform import platform
from traceback import print_exc
import milc
import milc.subcommand.config # noqa
from milc.questions import yesno
import platformdirs
from .helpers import broken_module_imports, find_qmk_firmware
from . import __version__
from .helpers import find_qmk_firmware, is_qmk_firmware, find_qmk_userspace, is_qmk_userspace
def _get_default_distrib_path():
if 'windows' in platform().lower():
try:
result = milc.cli.run(['cygpath', '-w', '/opt/qmk'])
if result.returncode == 0:
return result.stdout.strip()
except Exception:
pass
return platformdirs.user_data_dir('qmk')
# Ensure the QMK distribution is on the `$PATH` if present. This must be kept in sync with qmk/qmk_firmware.
QMK_DISTRIB_DIR = Path(os.environ.get('QMK_DISTRIB_DIR', _get_default_distrib_path()))
if QMK_DISTRIB_DIR.exists():
os.environ['PATH'] = str(QMK_DISTRIB_DIR / 'bin') + os.pathsep + os.environ['PATH']
# Prepend any user-defined path prefix
if 'QMK_PATH_PREFIX' in os.environ:
os.environ['PATH'] = os.environ['QMK_PATH_PREFIX'] + os.pathsep + os.environ['PATH']
milc.cli.milc_options(version=__version__)
milc.EMOJI_LOGLEVELS['INFO'] = '{fg_blue}Ψ{style_reset_all}'
# These must happen after the milc.milc_options() call
import milc.subcommand.config # noqa: E402, must come after milc.milc_options()
@milc.cli.entrypoint('CLI wrapper for running QMK commands.')
def qmk_main(cli):
@@ -42,61 +69,30 @@ def main():
"""Setup the environment before dispatching to the entrypoint.
"""
# Warn if they use an outdated python version
if sys.version_info < (3, 7):
if sys.version_info < (3, 9):
print('Warning: Your Python version is out of date! Some subcommands may not work!')
print('Please upgrade to Python 3.7 or later.')
if 'windows' in platform().lower():
msystem = os.environ.get('MSYSTEM', '')
if 'mingw64' not in sys.executable or 'MINGW64' not in msystem:
print('ERROR: It seems you are not using the MINGW64 terminal.')
print('Please close this terminal and open a new MSYS2 MinGW 64-bit terminal.')
print('Python: %s, MSYSTEM: %s' % (sys.executable, msystem))
exit(1)
print('Please upgrade to Python 3.9 or later.')
# Environment setup
import qmk_cli
milc.cli.version = qmk_cli.__version__
qmk_userspace = find_qmk_userspace()
qmk_firmware = find_qmk_firmware()
if is_qmk_userspace(qmk_userspace):
os.environ['QMK_USERSPACE'] = str(qmk_userspace)
elif 'QMK_USERSPACE' in os.environ: # Failed to find valid userspace, including what was in the environment if specified -- wipe any environment variable if present as it's clearly invalid.
os.environ.pop('QMK_USERSPACE')
os.environ['QMK_HOME'] = str(qmk_firmware)
os.environ['ORIG_CWD'] = os.getcwd()
import qmk_cli.subcommands
import qmk_cli.subcommands # noqa: F401
# Check out and initialize the qmk_firmware environment
if qmk_firmware.exists():
if is_qmk_firmware(qmk_firmware):
# All subcommands are run relative to the qmk_firmware root to make it easier to use the right copy of qmk_firmware.
os.chdir(str(qmk_firmware))
# Check to make sure we have all the requirements
broken_modules, broken_dev_modules = broken_module_imports()
msg_install = 'Please run `python3 -m pip install -r %s` to install required python dependencies.'
if broken_modules:
if yesno('Would you like to install the required Python modules?'):
run_cmd(sys.executable, '-m', 'pip', 'install', '-r', 'requirements.txt')
else:
print()
print(msg_install % (os.environ['QMK_HOME'] + '/requirements.txt',))
print()
exit(1)
if broken_dev_modules:
if yesno('Would you like to install the required developer Python modules?'):
run_cmd(sys.executable, '-m', 'pip', 'install', '-r', 'requirements.txt')
else:
print()
print(msg_install % (os.environ['QMK_HOME'] + '/requirements-dev.txt',))
print('You can also turn off developer mode: qmk config user.developer=None')
print()
exit(1)
# Environment looks good, include the qmk_firmware subcommands
sys.path.append(str(qmk_firmware / 'lib/python'))
try:
import qmk.cli # noqa
import qmk.cli # noqa: F401
except ImportError as e:
if qmk_firmware.name != 'qmk_firmware':
+4 -2
View File
@@ -2,5 +2,7 @@
We list each subcommand here explicitly because all the reliable ways of searching for modules are slow and delay startup.
"""
from . import clone # noqa
from . import setup # noqa
from . import clone # noqa: F401
from . import console # noqa: F401
from . import env # noqa: F401
from . import setup # noqa: F401
+10 -12
View File
@@ -5,26 +5,24 @@ from pathlib import Path
from milc import cli
from qmk_cli.git import git_clone
from qmk_cli.helpers import AbsPath
default_repo = 'qmk_firmware'
default_fork = 'qmk/' + default_repo
default_branch = 'master'
@cli.argument('--baseurl', default='https://github.com', help='The URL all git operations start from (Default: https://github.com)')
@cli.argument('-b', '--branch', default=default_branch, help='The branch to clone. Default: %s' % default_branch)
@cli.argument('destination', default=None, nargs='?', help='The directory to clone to. Default: (current directory)')
@cli.argument('fork', default=default_fork, nargs='?', help='The qmk_firmware fork to clone. Default: %s' % default_fork)
@cli.argument('--baseurl', arg_only=True, default='https://github.com', help='The URL all git operations start from (Default: https://github.com)')
@cli.argument('-b', '--branch', arg_only=True, default=default_branch, help='The branch to clone. Default: %s' % default_branch)
@cli.argument('destination', arg_only=True, default=Path(os.environ['ORIG_CWD']) / default_repo, type=AbsPath, nargs='?', help='The directory to clone to. Default: (current directory)')
@cli.argument('fork', arg_only=True, default=default_fork, nargs='?', help='The qmk_firmware fork to clone. Default: %s' % default_fork)
@cli.subcommand('Clone a qmk_firmware fork.')
def clone(cli):
if not cli.args.destination:
cli.args.destination = os.path.join(os.environ['ORIG_CWD'], default_fork.split('/')[-1])
git_url = '/'.join((cli.args.baseurl, cli.args.fork))
qmk_firmware = Path(cli.args.destination)
git_url = '/'.join((cli.config.clone.baseurl, cli.args.fork))
if qmk_firmware.exists():
# Exists (but not an empty dir)
if cli.args.destination.exists() and any(cli.args.destination.iterdir()):
cli.log.error('Destination already exists: %s', cli.args.destination)
exit(1)
return False
return git_clone(git_url, cli.args.destination, cli.config.clone.branch)
return git_clone(cli.args.destination, git_url, cli.args.branch)
+374
View File
@@ -0,0 +1,374 @@
"""Acquire debugging information from usb hid devices
cli implementation of https://www.pjrc.com/teensy/hid_listen.html
"""
from functools import lru_cache
from pathlib import Path
from platform import platform
from threading import Thread
from time import sleep, strftime
from milc import cli
from milc.questions import yesno
LOG_COLOR = {
'next': 0,
'colors': [
'{fg_blue}',
'{fg_cyan}',
'{fg_green}',
'{fg_magenta}',
'{fg_red}',
'{fg_yellow}',
],
}
KNOWN_BOOTLOADERS = {
# VID , PID
('03EB', '2045'): 'lufa-ms: LUFA Mass Storage Bootloader',
('03EB', '2067'): 'qmk-hid: HID Bootloader',
('03EB', '2FEF'): 'atmel-dfu: ATmega16U2',
('03EB', '2FF0'): 'atmel-dfu: ATmega32U2',
('03EB', '2FF3'): 'atmel-dfu: ATmega16U4',
('03EB', '2FF4'): 'atmel-dfu: ATmega32U4',
('03EB', '2FF9'): 'atmel-dfu: AT90USB64',
('03EB', '2FFA'): 'atmel-dfu: AT90USB162',
('03EB', '2FFB'): 'atmel-dfu: AT90USB128',
('03EB', '6124'): 'Microchip SAM-BA',
('0483', 'DF11'): 'stm32-dfu: STM32 BOOTLOADER',
('16C0', '05DC'): 'usbasploader: USBaspLoader',
('16C0', '05DF'): 'bootloadhid: HIDBoot',
('16C0', '0478'): 'halfkay: Teensy Halfkay',
('1B4F', '9203'): 'caterina: Pro Micro 3.3V',
('1B4F', '9205'): 'caterina: Pro Micro 5V',
('1B4F', '9207'): 'caterina: LilyPadUSB',
('1C11', 'B007'): 'kiibohd: Kiibohd DFU Bootloader',
('1EAF', '0003'): 'stm32duino: Maple 003',
('1FFB', '0101'): 'caterina: Pololu A-Star 32U4 Bootloader',
('2341', '0036'): 'caterina: Arduino Leonardo',
('2341', '0037'): 'caterina: Arduino Micro',
('239A', '000C'): 'caterina: Adafruit Feather 32U4',
('239A', '000D'): 'caterina: Adafruit ItsyBitsy 32U4 3v',
('239A', '000E'): 'caterina: Adafruit ItsyBitsy 32U4 5v',
('2A03', '0036'): 'caterina: Arduino Leonardo',
('2A03', '0037'): 'caterina: Arduino Micro',
('314B', '0106'): 'apm32-dfu: APM32 DFU ISP Mode',
('342D', 'DFA0'): 'wb32-dfu: WB32 Device in DFU Mode',
}
def install_deps():
"""Install the necessary dependencies for qmk console.
"""
this_platform = platform().lower()
if 'darwin' in this_platform or 'macos' in this_platform:
command = ['brew', 'install', 'hidapi']
elif 'linux' in this_platform:
command = ['sudo', 'apt', 'install', '-y', 'libhidapi-hidraw0', 'libusb-dev']
elif 'windows' in this_platform:
command = ['pacboy', 'sync', '--needed', '--noconfirm', '--disable-download-timeout', 'hidapi:x']
else:
cli.log.error('Unsupported platform: %s', this_platform)
if yesno("Would you like to run `%s` to install the necessary package?", ' '.join(command)):
cli.run(command, capture_output=False)
return True
@lru_cache(maxsize=0)
def import_usb_core():
"""Attempts to import the usb.core module.
"""
try:
import usb.core
return usb.core
except ImportError as e:
cli.log.error('Could not import usb.core: %s', e)
if install_deps():
return import_usb_core()
raise
def import_hid():
"""Attempts to import the hid module.
"""
import os
old_cwd = os.getcwd()
try:
# macOS library search paths don't include homebrew by default when launched via a `uv`-based deployment.
# The `hid` python module does a search and attempts to load a set of known library names, but doesn't qualify the path, nor gives the option to do so.
# To work around this, we chdir to the homebrew lib directory before importing hid, then chdir back to where we were.
if 'darwin' in platform().lower() or 'macos' in platform().lower():
for path in ('/opt/homebrew/lib', '/usr/local/lib'):
lib_search = Path(path) / 'libhidapi.dylib'
if lib_search.exists():
os.chdir(path)
break
import hid
return hid
except ImportError as e:
cli.log.error('Could not import hid: %s', e)
if install_deps():
return import_hid()
raise
finally:
os.chdir(old_cwd)
class MonitorDevice(object):
def __init__(self, hid_device, numeric):
self.hid = import_hid()
self.hid_device = hid_device
self.numeric = numeric
self.device = self.hid.Device(path=hid_device['path'])
self.current_line = ''
cli.log.info('Console Connected: %(color)s%(manufacturer_string)s %(product_string)s{style_reset_all} (%(color)s%(vendor_id)04X:%(product_id)04X:%(index)d{style_reset_all})', hid_device)
def read(self, size, encoding='ascii', timeout=1):
"""Read size bytes from the device.
"""
return self.device.read(size, timeout).decode(encoding)
def read_line(self):
"""Read from the device's console until we get a \n.
"""
while '\n' not in self.current_line:
self.current_line += self.read(32).replace('\x00', '')
lines = self.current_line.split('\n', 1)
self.current_line = lines[1]
return lines[0]
def run_forever(self):
while True:
try:
message = {**self.hid_device, 'text': self.read_line()}
identifier = (int2hex(message['vendor_id']), int2hex(message['product_id'])) if self.numeric else (message['manufacturer_string'], message['product_string'])
message['identifier'] = ':'.join(identifier)
message['ts'] = '{style_dim}{fg_green}%s{style_reset_all} ' % (strftime(cli.config.general.datetime_fmt),) if cli.args.timestamp else ''
cli.echo('%s', '%(ts)s%(color)s%(identifier)s:%(index)d{style_reset_all}: %(text)s' % message)
except self.hid.HIDException:
break
class FindDevices(object):
def __init__(self, vid, pid, index, numeric):
self.hid = import_hid()
self.vid = vid
self.pid = pid
self.index = index
self.numeric = numeric
def run_forever(self):
"""Process messages from our queue in a loop.
"""
live_devices = {}
live_bootloaders = {}
while True:
try:
for device in list(live_devices):
if not live_devices[device]['thread'].is_alive():
cli.log.info('Console Disconnected: %(color)s%(manufacturer_string)s %(product_string)s{style_reset_all} (%(color)s%(vendor_id)04X:%(product_id)04X:%(index)d{style_reset_all})', live_devices[device])
del live_devices[device]
for device in self.find_devices():
if device['path'] not in live_devices:
device['color'] = LOG_COLOR['colors'][LOG_COLOR['next']]
LOG_COLOR['next'] = (LOG_COLOR['next'] + 1) % len(LOG_COLOR['colors'])
live_devices[device['path']] = device
try:
monitor = MonitorDevice(device, self.numeric)
device['thread'] = Thread(target=monitor.run_forever, daemon=True)
device['thread'].start()
except Exception as e:
device['e'] = e
device['e_name'] = e.__class__.__name__
cli.log.error("Could not connect to %(color)s%(manufacturer_string)s %(product_string)s{style_reset_all} (%(color)s%(vendor_id)04X:%(product_id)04X:%(index)d{style_reset_all}): %(e_name)s: %(e)s", device)
if cli.config.general.verbose:
cli.log.exception(e)
del live_devices[device['path']]
if cli.args.bootloaders:
for device in self.find_bootloaders():
if device.address in live_bootloaders:
live_bootloaders[device.address]._qmk_found = True
else:
name = KNOWN_BOOTLOADERS[(int2hex(device.idVendor), int2hex(device.idProduct))]
cli.log.info('Bootloader Connected: {style_bright}{fg_magenta}%s', name)
device._qmk_found = True
live_bootloaders[device.address] = device
for device in list(live_bootloaders):
if live_bootloaders[device]._qmk_found:
live_bootloaders[device]._qmk_found = False
else:
name = KNOWN_BOOTLOADERS[(int2hex(live_bootloaders[device].idVendor), int2hex(live_bootloaders[device].idProduct))]
cli.log.info('Bootloader Disconnected: {style_bright}{fg_magenta}%s', name)
del live_bootloaders[device]
sleep(.1)
except KeyboardInterrupt:
break
def is_bootloader(self, hid_device):
"""Returns true if the device in question matches a known bootloader vid/pid.
"""
return (int2hex(hid_device.idVendor), int2hex(hid_device.idProduct)) in KNOWN_BOOTLOADERS
def is_console_hid(self, hid_device):
"""Returns true when the usage page indicates it's a teensy-style console.
"""
return hid_device['usage_page'] == 0xFF31 and hid_device['usage'] == 0x0074
def is_filtered_device(self, hid_device):
"""Returns True if the device should be included in the list of available consoles.
"""
return int2hex(hid_device['vendor_id']) == self.vid and int2hex(hid_device['product_id']) == self.pid
def find_devices_by_report(self, hid_devices):
"""Returns a list of available teensy-style consoles by doing a brute-force search.
Some versions of linux don't report usage and usage_page. In that case we fallback to reading the report (possibly inaccurately) ourselves.
"""
devices = []
for device in hid_devices:
path = device['path'].decode('utf-8')
if path.startswith('/dev/hidraw'):
number = path[11:]
report = Path(f'/sys/class/hidraw/hidraw{number}/device/report_descriptor')
if report.exists():
rp = report.read_bytes()
if rp[1] == 0x31 and rp[3] == 0x09:
devices.append(device)
return devices
def find_bootloaders(self):
"""Returns a list of available bootloader devices.
"""
import usb.core
return list(filter(self.is_bootloader, usb.core.find(find_all=True)))
def find_devices(self):
"""Returns a list of available teensy-style consoles.
"""
hid_devices = self.hid.enumerate()
devices = list(filter(self.is_console_hid, hid_devices))
if not devices:
devices = self.find_devices_by_report(hid_devices)
if self.vid and self.pid:
devices = list(filter(self.is_filtered_device, devices))
# Add index numbers
device_index = {}
for device in devices:
id = ':'.join((int2hex(device['vendor_id']), int2hex(device['product_id'])))
if id not in device_index:
device_index[id] = 0
device_index[id] += 1
device['index'] = device_index[id]
return devices
def int2hex(number):
"""Returns a string representation of the number as hex.
"""
return "%04X" % number
def list_devices(device_finder):
"""Show the user a nicely formatted list of devices.
"""
devices = device_finder.find_devices()
if devices:
cli.log.info('Available devices:')
for dev in devices:
color = LOG_COLOR['colors'][LOG_COLOR['next']]
LOG_COLOR['next'] = (LOG_COLOR['next'] + 1) % len(LOG_COLOR['colors'])
cli.log.info("\t%s%s:%s:%d{style_reset_all}\t%s %s", color, int2hex(dev['vendor_id']), int2hex(dev['product_id']), dev['index'], dev['manufacturer_string'], dev['product_string'])
if cli.args.bootloaders:
bootloaders = device_finder.find_bootloaders()
if bootloaders:
cli.log.info('Available Bootloaders:')
for dev in bootloaders:
cli.log.info("\t%s:%s\t%s", int2hex(dev.idVendor), int2hex(dev.idProduct), KNOWN_BOOTLOADERS[(int2hex(dev.idVendor), int2hex(dev.idProduct))])
@cli.argument('--bootloaders', arg_only=True, default=True, action='store_boolean', help='displaying bootloaders.')
@cli.argument('-d', '--device', help='Device to select - uses format <pid>:<vid>[:<index>].')
@cli.argument('-l', '--list', arg_only=True, action='store_true', help='List available hid_listen devices.')
@cli.argument('-n', '--numeric', arg_only=True, action='store_true', help='Show VID/PID instead of names.')
@cli.argument('-t', '--timestamp', arg_only=True, action='store_true', help='Print the timestamp for received messages as well.')
@cli.argument('-w', '--wait', type=int, default=1, help="How many seconds to wait between checks (Default: 1)")
@cli.subcommand('Acquire debugging information from usb hid devices.')
def console(cli):
"""Acquire debugging information from usb hid devices
"""
vid = None
pid = None
index = 1
if cli.config.console.device:
device = cli.config.console.device.split(':')
if len(device) == 2:
vid, pid = device
elif len(device) == 3:
vid, pid, index = device
if not index.isdigit():
cli.log.error('Device index must be a number! Got "%s" instead.', index)
exit(1)
index = int(index)
if index < 1:
cli.log.error('Device index must be greater than 0! Got %s', index)
exit(1)
else:
cli.log.error('Invalid format for device, expected "<pid>:<vid>[:<index>]" but got "%s".', cli.config.console.device)
cli.print_help()
exit(1)
vid = vid.upper()
pid = pid.upper()
device_finder = FindDevices(vid, pid, index, cli.args.numeric)
if cli.args.list:
return list_devices(device_finder)
print('Looking for devices...', flush=True)
device_finder.run_forever()
+39
View File
@@ -0,0 +1,39 @@
"""Prints environment information.
"""
import os
import sys
from pathlib import Path
from milc import cli
from qmk_cli.helpers import is_qmk_firmware, is_qmk_userspace
@cli.argument('var', arg_only=True, default=None, nargs='?', help='Optional variable to query')
@cli.subcommand('Prints environment information.')
def env(cli):
home = os.environ.get('QMK_HOME', "")
userspace = os.environ.get('QMK_USERSPACE', "")
data = {
'QMK_HOME': home,
'QMK_FIRMWARE': home if is_qmk_firmware(Path(home)) else "",
'QMK_USERSPACE': userspace if is_qmk_userspace(Path(userspace)) else "",
'QMK_DISTRIB_DIR': os.environ.get('QMK_DISTRIB_DIR', ""),
'QMK_PATH_PREFIX': os.environ.get('QMK_PATH_PREFIX', ""),
}
# Now munge the current cli config
for key, val in cli.config.general.items():
converted_key = 'QMK_' + key.upper()
data[converted_key] = val
if cli.args.var:
if cli.args.var not in data:
print(f'Variable "{cli.args.var}" does not exist!', file=sys.stderr)
return False
# dump out requested arg
print(data[cli.args.var])
else:
# dump out everything
for key, val in data.items():
print(f'{key}="{val}"')
+58 -72
View File
@@ -2,72 +2,28 @@
"""
import os
import shlex
import subprocess
import sys
from pathlib import Path
from milc import cli
from milc.questions import yesno
from qmk_cli.git import git_clone
from milc.questions import choice, question, yesno
from qmk_cli.git import git_clone_fork
from qmk_cli.helpers import AbsPath, is_qmk_firmware
default_base = 'https://github.com'
default_repo = 'qmk_firmware'
default_fork = 'qmk/' + default_repo
default_branch = 'master'
def git_upstream(destination):
"""Add the qmk/qmk_firmware upstream to a qmk_firmware clone.
"""
git_url = '/'.join((cli.config.setup.baseurl, default_fork))
git_cmd = [
'git',
'-C',
destination,
'remote',
'add',
'upstream',
git_url,
]
with subprocess.Popen(git_cmd, stderr=subprocess.STDOUT, stdout=subprocess.PIPE, bufsize=1, universal_newlines=True, encoding='utf-8') as p:
for line in p.stdout:
print(line, end='')
if p.returncode == 0:
cli.log.info('Added %s as remote upstream.', git_url)
return True
else:
cli.log.error('%s exited %d', ' '.join(git_cmd), p.returncode)
return False
def is_qmk_firmware(qmk_firmware):
"""Returns True if the given Path() is a qmk_firmware clone.
"""
paths = [
qmk_firmware,
qmk_firmware / 'Makefile',
qmk_firmware / 'requirements.txt',
qmk_firmware / 'requirements-dev.txt',
qmk_firmware / 'lib/python/qmk/cli/doctor.py'
]
for path in paths:
if not path.exists():
return False
return True
DEFAULT_BASE = 'https://github.com'
DEFAULT_REPO = 'qmk_firmware'
DEFAULT_FORK = 'qmk/' + DEFAULT_REPO
DEFAULT_BRANCH = 'master'
@cli.argument('-n', '--no', arg_only=True, action='store_true', help='Answer no to all questions')
@cli.argument('-y', '--yes', arg_only=True, action='store_true', help='Answer yes to all questions')
@cli.argument('--baseurl', default=default_base, help='The URL all git operations start from. Default: %s' % default_base)
@cli.argument('-b', '--branch', default=default_branch, help='The branch to clone. Default: %s' % default_branch)
@cli.argument('-H', '--home', default=Path(os.environ['QMK_HOME']), type=Path, help='The location for QMK Firmware. Default: %s' % os.environ['QMK_HOME'])
@cli.argument('fork', default=default_fork, nargs='?', help='The qmk_firmware fork to clone. Default: %s' % default_fork)
@cli.argument('--baseurl', arg_only=True, default=DEFAULT_BASE, help='The URL all git operations start from. Default: %s' % DEFAULT_BASE)
@cli.argument('-b', '--branch', arg_only=True, default=DEFAULT_BRANCH, help='The branch to clone. Default: %s' % DEFAULT_BRANCH)
@cli.argument('-H', '--home', arg_only=True, default=Path(os.environ['QMK_HOME']), type=AbsPath, help='The location for QMK Firmware. Default: %s' % os.environ['QMK_HOME'])
@cli.argument('fork', arg_only=True, default=DEFAULT_FORK, nargs='?', help='The qmk_firmware fork to clone. Default: %s' % DEFAULT_FORK)
@cli.subcommand('Setup your computer for qmk_firmware.')
def setup(cli):
def setup(cli): # noqa: C901
"""Guide the user through setting up their QMK environment.
"""
clone_prompt = 'Would you like to clone {fg_cyan}%s{fg_reset} to {fg_cyan}%s{fg_reset}?' % (cli.args.fork, shlex.quote(str(cli.args.home)))
@@ -76,43 +32,73 @@ def setup(cli):
# Sanity checks
if cli.args.yes and cli.args.no:
cli.log.error("Can't use both --yes and --no at the same time.")
exit(1)
return False
# Check on qmk_firmware, and if it doesn't exist offer to check it out.
# Check on qmk_firmware
# If it exists, ask the user what to do with it
# If it doesn't exist, offer to check it out
if is_qmk_firmware(cli.args.home):
cli.log.info('Found qmk_firmware at %s.', str(cli.args.home))
found_prompt = "What do you want to do?"
found_options = [
f"Delete and reclone {cli.args.fork}",
"Delete and clone a different fork",
"Keep it and continue",
]
delete_confirm = "WARNING: This will delete your current qmk_firmware directory. Proceed?"
elif cli.args.home.exists():
found_action = choice(found_prompt, options=found_options, default=2)
if found_action == f"Delete and reclone {cli.args.fork}":
if not yesno(delete_confirm, default=False):
return False
if not git_clone_fork(cli.args.home, cli.args.baseurl, cli.args.fork, cli.args.branch, force=True):
return False
elif found_action == "Delete and clone a different fork":
fork_name = question("Enter the name of the fork:", default=cli.args.fork)
branch_name = question("Enter the branch name to clone:", default=cli.args.branch)
if not yesno(delete_confirm, default=False):
return False
if not git_clone_fork(cli.args.home, cli.args.baseurl, fork_name, branch_name, force=True):
return False
# Exists (but not an empty dir)
elif cli.args.home.exists() and any(cli.args.home.iterdir()):
path_str = str(cli.args.home)
if cli.args.home.name != 'qmk_firmware':
cli.log.warning('Warning: %s does not end in "qmk_firmware". Did you mean to use "--home %s/qmk_firmware"?' % (path_str, path_str))
cli.log.error("Path '%s' exists but is not a qmk_firmware clone!", path_str)
exit(1)
return False
else:
cli.log.error('Could not find qmk_firmware!')
if yesno(clone_prompt):
git_url = '/'.join((cli.config.setup.baseurl, cli.args.fork))
if git_clone(git_url, cli.args.home, cli.config.setup.branch):
git_upstream(cli.args.home)
else:
exit(1)
if not git_clone_fork(cli.args.home, cli.args.baseurl, cli.args.fork, cli.args.branch):
return False
else:
cli.log.warning('Not cloning qmk_firmware due to user input or --no flag.')
# Offer to set `user.qmk_home` for them.
if str(cli.args.home) != os.environ['QMK_HOME'] and yesno(home_prompt):
cli.config['user']['qmk_home'] = str(cli.args.home.absolute())
cli.config_source['user']['qmk_home'] = 'config_file'
cli.write_config_option('user', 'qmk_home')
# Run `qmk doctor` to check the rest of the environment out
doctor_command = [sys.executable, sys.argv[0], 'doctor']
if cli.args.home.exists():
color = '--color' if cli.config.general.color else '--no-color'
unicode = '--unicode' if cli.config.general.unicode else '--no-unicode'
doctor_command = [Path(sys.argv[0]).as_posix(), color, unicode, 'doctor']
if cli.args.no:
doctor_command.append('--no')
if cli.args.no:
doctor_command.append('-n')
if cli.args.yes:
doctor_command.append('--yes')
if cli.args.yes:
doctor_command.append('-y')
cli.run(doctor_command, capture_output=False)
cli.run(doctor_command, stdin=None, capture_output=False, cwd=cli.args.home)
-32
View File
@@ -1,32 +0,0 @@
#!/bin/bash
# Increment the verison number and release a new version of qmk_cli.
#
# Required packages: pip3 install bumpversion twine
set -e
set -x
PYPI_USERNAME=${PYPI_USERNAME:=skully}
FLIT_USERNAME=$PYPI_USERNAME
TWINE_USERNAME=$PYPI_USERNAME
export FLIT_USERNAME TWINE_USERNAME
if ! bumpversion -h &> /dev/null; then
echo "Missing bumpversion! Please run: pip3 install -U -r requirements-dev.txt"
exit 1
fi
if ! twine -h &> /dev/null; then
echo "Missing twine! Please run: pip3 install -U -r requirements-dev.txt"
exit 1
fi
# Bump the version, tag, and push
rm -f dist/*
bumpversion patch
git push origin master --tags
# Build and upload
python3 setup.py sdist bdist_wheel
twine upload dist/qmk-*
-2
View File
@@ -1,2 +0,0 @@
bumpversion
twine
-82
View File
@@ -1,82 +0,0 @@
[bumpversion]
current_version = 0.0.41
commit = True
tag = True
tag_name = {new_version}
message = New release: {current_version} → {new_version}
[bumpversion:file:qmk_cli/__init__.py]
[bumpversion:file:setup.cfg]
[bdist_wheel]
universal = 1
[flake8]
ignore = E501,E226
[metadata]
author = skullydazed
author-email = skullydazed@gmail.com
description-file = README.md
dist-name = qmk
license_file = LICENSE
module = qmk_cli
home-page = https://github.com/qmk/qmk_cli
requires-python = >=3.7
[entry_points]
qmk = qmk_cli.script_qmk:main
[yapf]
align_closing_bracket_with_visual_indent = True
allow_multiline_dictionary_keys = False
allow_multiline_lambdas = False
allow_split_before_default_or_named_assigns = True
allow_split_before_dict_value = True
arithmetic_precedence_indication = True
blank_lines_around_top_level_definition = 2
blank_line_before_class_docstring = False
blank_line_before_module_docstring = False
blank_line_before_nested_class_or_def = False
coalesce_brackets = True
column_limit = 256
continuation_align_style = SPACE
continuation_indent_width = 4
dedent_closing_brackets = True
disable_ending_comma_heuristic = False
each_dict_entry_on_separate_line = True
i18n_comment =
i18n_function_call =
indent_blank_lines = False
indent_dictionary_value = True
indent_width = 4
join_multiple_lines = False
no_spaces_around_selected_binary_operators =
spaces_around_default_or_named_assign = False
spaces_around_power_operator = False
spaces_before_comment = 2
space_between_ending_comma_and_closing_bracket = False
split_all_comma_separated_values = False
split_arguments_when_comma_terminated = True
split_before_arithmetic_operator = False
split_before_bitwise_operator = True
split_before_closing_bracket = True
split_before_dict_set_generator = True
split_before_dot = False
split_before_expression_after_opening_paren = False
split_before_first_argument = False
split_before_logical_operator = False
split_before_named_assigns = True
split_complex_comprehension = True
split_penalty_after_opening_bracket = 300
split_penalty_after_unary_operator = 10000
split_penalty_arithmetic_operator = 300
split_penalty_before_if_expr = 0
split_penalty_bitwise_operator = 300
split_penalty_comprehension = 80
split_penalty_excess_character = 7000
split_penalty_for_added_line_split = 30
split_penalty_import_names = 0
split_penalty_logical_operator = 300
use_tabs = False
-55
View File
@@ -1,55 +0,0 @@
from configparser import ConfigParser
from setuptools import setup, find_packages
setup_cfg = ConfigParser()
setup_cfg.read('setup.cfg')
metadata = setup_cfg['metadata']
if __name__ == "__main__":
with open('README.md', encoding='utf-8') as readme_file:
long_description = readme_file.read()
setup(
name=metadata['dist-name'],
description='A program to help users work with QMK Firmware.',
entry_points={
'console_scripts': ['%s = %s' % i for i in setup_cfg['entry_points'].items()],
},
license='MIT License',
url=metadata['home-page'],
version=setup_cfg['bumpversion']['current_version'],
author=metadata['author'],
author_email=metadata['author-email'],
maintainer=metadata['author'],
maintainer_email=metadata['author-email'],
long_description=long_description,
long_description_content_type="text/markdown",
packages=find_packages(),
py_modules=['milc'],
classifiers=[
'Development Status :: 3 - Alpha',
'Environment :: Console',
'Intended Audience :: Developers',
'Intended Audience :: System Administrators',
'Intended Audience :: End Users/Desktop',
'License :: OSI Approved :: MIT License',
'Natural Language :: English',
'Programming Language :: Python :: 3 :: Only',
'Topic :: Scientific/Engineering',
'Topic :: Software Development',
'Topic :: Utilities',
],
python_requires=metadata['requires-python'],
install_requires=[
"appdirs",
"argcomplete",
"colorama",
"dotty-dict",
"flake8",
"hjson",
"jsonschema>=3",
"milc>=1.0.8",
"nose2",
"pygments",
"yapf"
],
)
+39
View File
@@ -0,0 +1,39 @@
import tempfile
import pytest
from pathlib import Path
from unittest.mock import create_autospec, PropertyMock, MagicMock
from milc import MILCInterface
from milc.configuration import Configuration
def pytest_addoption(parser):
parser.addoption(
'--qmk',
action='store',
default='wrapper',
help='options: ./qmk wrapper or real qmk from path',
choices=('wrapper', 'real'),
)
@pytest.fixture
def temp_directory():
"""Similar behavior to the default tmpdir fixture except the folder is cleaned up."""
with tempfile.TemporaryDirectory() as tmp_path:
yield Path(tmp_path)
@pytest.fixture
def mock_cli():
"""Mock cli to pass to cli subcommands,"""
ret = create_autospec(MILCInterface)
# default behavior
type(ret).config = Configuration()
ret.config.general.unicode = True
ret.config.general.color = True
type(ret).write_config_option = MagicMock()
type(ret.args).var = PropertyMock(return_value=None)
return ret
+40
View File
@@ -0,0 +1,40 @@
import pytest
from unittest.mock import patch, PropertyMock
@pytest.fixture
def subcommand(temp_directory):
tmp = temp_directory.as_posix()
with patch.dict('os.environ', {'ORIG_CWD': tmp, 'QMK_HOME': tmp}, clear=True):
import qmk_cli.subcommands.clone as clone
yield clone
@pytest.fixture
def git_clone(subcommand):
with patch.object(subcommand, 'git_clone') as git_clone:
yield git_clone
def test_clone(subcommand, mock_cli, git_clone):
type(mock_cli.args).baseurl = PropertyMock(return_value='asdf')
type(mock_cli.args).fork = PropertyMock(return_value='fork')
git_clone.return_value = True
ret = subcommand.clone(mock_cli)
git_clone.assert_called_once()
assert ret is True
def test_clone_not_empty(subcommand, mock_cli, temp_directory, git_clone):
type(mock_cli.args).baseurl = PropertyMock(return_value='asdf')
type(mock_cli.args).fork = PropertyMock(return_value='fork')
type(mock_cli.args).destination = PropertyMock(return_value=temp_directory)
(temp_directory / 'asdf').touch()
ret = subcommand.clone(mock_cli)
git_clone.assert_not_called()
assert ret is False
+51
View File
@@ -0,0 +1,51 @@
import pytest
from unittest.mock import patch, PropertyMock
@pytest.fixture
def subcommand(temp_directory):
tmp = temp_directory.as_posix()
with patch.dict('os.environ', {'ORIG_CWD': tmp, 'QMK_HOME': tmp}, clear=True):
import qmk_cli.subcommands.env as env
yield env
@pytest.fixture
def is_qmk_firmware(subcommand):
with patch.object(subcommand, 'is_qmk_firmware') as is_qmk_firmware:
is_qmk_firmware.return_value = True
yield is_qmk_firmware
def test_request_qmk_firmware_exists(subcommand, mock_cli, capsys, temp_directory, is_qmk_firmware):
subcommand.env(mock_cli)
captured = capsys.readouterr().out
assert f'QMK_HOME="{temp_directory}"' in captured
assert f'QMK_FIRMWARE="{temp_directory}"' in captured
def test_request_all_variables(subcommand, mock_cli, capsys, temp_directory):
subcommand.env(mock_cli)
captured = capsys.readouterr().out
assert f'QMK_HOME="{temp_directory}"' in captured
assert 'QMK_FIRMWARE=""' in captured
assert 'QMK_UNICODE="True"' in captured
def test_request_single_variable(subcommand, mock_cli, capsys, temp_directory):
type(mock_cli.args).var = PropertyMock(return_value='QMK_HOME')
subcommand.env(mock_cli)
captured = capsys.readouterr().out
assert captured == f'{temp_directory}\n'
def test_request_single_variable_no_exits(subcommand, mock_cli, capsys):
type(mock_cli.args).var = PropertyMock(return_value='ASDF')
ret = subcommand.env(mock_cli)
captured = capsys.readouterr().err
assert captured == 'Variable "ASDF" does not exist!\n'
assert ret is False
+221
View File
@@ -0,0 +1,221 @@
import pytest
from unittest.mock import patch, PropertyMock, ANY
@pytest.fixture
def subcommand(temp_directory):
tmp = temp_directory.as_posix()
with patch.dict('os.environ', {'ORIG_CWD': tmp, 'QMK_HOME': tmp}, clear=True):
import qmk_cli.subcommands.setup as setup
yield setup
@pytest.fixture
def is_qmk_firmware(subcommand):
with patch.object(subcommand, 'is_qmk_firmware') as is_qmk_firmware:
is_qmk_firmware.return_value = True
yield is_qmk_firmware
@pytest.fixture
def yesno(subcommand):
with patch.object(subcommand, 'yesno') as yesno:
yesno.return_value = True
yield yesno
@pytest.fixture
def choice(subcommand):
with patch.object(subcommand, 'choice') as choice:
yield choice
@pytest.fixture
def question(subcommand):
with patch.object(subcommand, 'question') as question:
yield question
@pytest.fixture
def git_clone_fork(subcommand):
with patch.object(subcommand, 'git_clone_fork') as git_clone_fork:
yield git_clone_fork
def test_setup_both_yes_no_invalid(subcommand, mock_cli):
type(mock_cli.args).yes = PropertyMock(return_value=True)
type(mock_cli.args).no = PropertyMock(return_value=True)
ret = subcommand.setup(mock_cli)
assert ret is False
def test_setup_reclone(subcommand, mock_cli, is_qmk_firmware, temp_directory, yesno, choice, git_clone_fork):
type(mock_cli.args).yes = PropertyMock(return_value=False)
type(mock_cli.args).no = PropertyMock(return_value=False)
type(mock_cli.args).home = PropertyMock(return_value=temp_directory)
type(mock_cli.args).fork = 'asdf'
choice.return_value = 'Delete and reclone asdf'
yesno.return_value = True
subcommand.setup(mock_cli)
yesno.assert_called_once()
assert 'This will delete your current qmk_firmware directory.' in yesno.call_args.args[0]
git_clone_fork.assert_called_once()
def test_setup_reclone_failed(subcommand, mock_cli, is_qmk_firmware, temp_directory, yesno, choice, git_clone_fork):
type(mock_cli.args).yes = PropertyMock(return_value=False)
type(mock_cli.args).no = PropertyMock(return_value=False)
type(mock_cli.args).home = PropertyMock(return_value=temp_directory)
type(mock_cli.args).fork = 'asdf'
choice.return_value = 'Delete and reclone asdf'
yesno.return_value = True
git_clone_fork.return_value = False
ret = subcommand.setup(mock_cli)
yesno.assert_called_once()
assert 'This will delete your current qmk_firmware directory.' in yesno.call_args.args[0]
git_clone_fork.assert_called_once()
assert ret is False
def test_setup_reclone_no(subcommand, mock_cli, is_qmk_firmware, temp_directory, yesno, choice, git_clone_fork):
type(mock_cli.args).yes = PropertyMock(return_value=False)
type(mock_cli.args).no = PropertyMock(return_value=False)
type(mock_cli.args).home = PropertyMock(return_value=temp_directory)
type(mock_cli.args).fork = 'asdf'
choice.return_value = 'Delete and reclone asdf'
yesno.return_value = False
ret = subcommand.setup(mock_cli)
assert ret is False
git_clone_fork.assert_not_called()
def test_setup_clone_diff_fork(subcommand, mock_cli, is_qmk_firmware, temp_directory, yesno, choice, question, git_clone_fork):
type(mock_cli.args).yes = PropertyMock(return_value=False)
type(mock_cli.args).no = PropertyMock(return_value=False)
type(mock_cli.args).home = PropertyMock(return_value=temp_directory)
choice.return_value = 'Delete and clone a different fork'
yesno.return_value = True
subcommand.setup(mock_cli)
yesno.assert_called_once()
assert 'This will delete your current qmk_firmware directory.' in yesno.call_args.args[0]
git_clone_fork.assert_called_once()
def test_setup_clone_diff_fork_failed(subcommand, mock_cli, is_qmk_firmware, temp_directory, yesno, choice, question, git_clone_fork):
type(mock_cli.args).yes = PropertyMock(return_value=False)
type(mock_cli.args).no = PropertyMock(return_value=False)
type(mock_cli.args).home = PropertyMock(return_value=temp_directory)
choice.return_value = 'Delete and clone a different fork'
yesno.return_value = True
git_clone_fork.return_value = False
ret = subcommand.setup(mock_cli)
yesno.assert_called_once()
assert 'This will delete your current qmk_firmware directory.' in yesno.call_args.args[0]
git_clone_fork.assert_called_once()
assert ret is False
def test_setup_clone_diff_fork_no(subcommand, mock_cli, is_qmk_firmware, temp_directory, yesno, choice, question, git_clone_fork):
type(mock_cli.args).yes = PropertyMock(return_value=False)
type(mock_cli.args).no = PropertyMock(return_value=False)
type(mock_cli.args).home = PropertyMock(return_value=temp_directory)
choice.return_value = 'Delete and clone a different fork'
yesno.return_value = False
ret = subcommand.setup(mock_cli)
assert ret is False
git_clone_fork.assert_not_called()
def test_setup_home_exists_not_empty(subcommand, mock_cli, is_qmk_firmware, temp_directory):
type(mock_cli.args).yes = PropertyMock(return_value=False)
type(mock_cli.args).no = PropertyMock(return_value=False)
type(mock_cli.args).home = PropertyMock(return_value=temp_directory)
is_qmk_firmware.return_value = False
(temp_directory / 'asdf').touch()
ret = subcommand.setup(mock_cli)
assert ret is False
def test_setup_missing(subcommand, mock_cli, is_qmk_firmware, temp_directory, yesno, git_clone_fork):
type(mock_cli.args).yes = PropertyMock(return_value=False)
type(mock_cli.args).no = PropertyMock(return_value=False)
type(mock_cli.args).home = PropertyMock(return_value=temp_directory)
is_qmk_firmware.return_value = False
yesno.return_value = True
subcommand.setup(mock_cli)
yesno.assert_called_once()
assert 'Would you like to clone' in yesno.call_args.args[0]
git_clone_fork.assert_called_once()
def test_setup_missing_failed(subcommand, mock_cli, is_qmk_firmware, temp_directory, yesno, git_clone_fork):
type(mock_cli.args).yes = PropertyMock(return_value=False)
type(mock_cli.args).no = PropertyMock(return_value=False)
type(mock_cli.args).home = PropertyMock(return_value=temp_directory)
is_qmk_firmware.return_value = False
yesno.return_value = True
git_clone_fork.return_value = False
ret = subcommand.setup(mock_cli)
yesno.assert_called_once()
assert 'Would you like to clone' in yesno.call_args.args[0]
git_clone_fork.assert_called_once()
assert ret is False
def test_setup_missing_no(subcommand, mock_cli, is_qmk_firmware, temp_directory, yesno, git_clone_fork):
type(mock_cli.args).yes = PropertyMock(return_value=False)
type(mock_cli.args).no = PropertyMock(return_value=False)
type(mock_cli.args).home = PropertyMock(return_value=temp_directory)
is_qmk_firmware.return_value = False
yesno.return_value = False
subcommand.setup(mock_cli)
yesno.assert_called_once()
assert 'Would you like to clone' in yesno.call_args.args[0]
git_clone_fork.assert_not_called()
def test_setup_chains_args_to_doctor(subcommand, mock_cli, is_qmk_firmware, yesno, choice, git_clone_fork):
type(mock_cli.args).yes = PropertyMock(return_value=True)
type(mock_cli.args).no = PropertyMock(return_value=False)
subcommand.setup(mock_cli)
mock_cli.run.assert_called_once()
assert mock_cli.run.call_args.args[0] == [ANY, '--color', '--unicode', 'doctor', '-y']
def test_setup_chains_args_to_doctor_no(subcommand, mock_cli, is_qmk_firmware, yesno, choice, git_clone_fork):
type(mock_cli.args).yes = PropertyMock(return_value=False)
type(mock_cli.args).no = PropertyMock(return_value=True)
mock_cli.config.general.color = False
mock_cli.config.general.unicode = False
subcommand.setup(mock_cli)
mock_cli.run.assert_called_once()
assert mock_cli.run.call_args.args[0] == [ANY, '--no-color', '--no-unicode', 'doctor', '-n']
+46
View File
@@ -0,0 +1,46 @@
import pytest
import subprocess
@pytest.fixture(autouse=True)
def temp_env(temp_directory, monkeypatch):
qmk_firmware = temp_directory / 'qmk_firmware'
monkeypatch.setenv("QMK_HOME", qmk_firmware.as_posix())
yield qmk_firmware
@pytest.fixture
def run_cli(request):
def run_cli_wrapper(args):
cmd = f'{request.config.rootpath}/qmk' if request.config.getoption("--qmk") == 'wrapper' else 'qmk'
return subprocess.run([cmd, *args], capture_output=True, text=True)
return run_cli_wrapper
@pytest.mark.system
def test_cli_help(run_cli):
completed_process = run_cli(['clone', '--help'])
assert 'usage:' in completed_process.stdout
assert completed_process.returncode == 0
@pytest.mark.system
def test_cli_setup_no(run_cli):
completed_process = run_cli(['setup', '-n'])
assert 'Could not find qmk_firmware!' in completed_process.stderr
assert 'Not cloning qmk_firmware due to user input or --no flag.' in completed_process.stderr
assert completed_process.returncode == 0
@pytest.mark.system
def test_cli_setup_yes(run_cli):
completed_process = run_cli(['setup', '-y'])
assert 'Successfully cloned https://github.com/qmk/qmk_firmware' in completed_process.stderr
assert 'Added https://github.com/qmk/qmk_firmware as remote upstream' in completed_process.stderr
assert 'QMK Doctor is checking your environment' in completed_process.stderr
assert completed_process.returncode == 0
+117
View File
@@ -0,0 +1,117 @@
import pytest
import subprocess
from unittest.mock import patch, PropertyMock
import qmk_cli.git
@patch("qmk_cli.git.subprocess.Popen", side_effect=Exception("foobar"))
@patch("qmk_cli.git.cli.log.error")
def test_git_clone_except(mock_log_error, mock_popen):
ret = qmk_cli.git.git_clone('/tmp', 'https://github.com/qmk/qmk_firmware', 'master')
assert "Could not run" in str(mock_log_error.call_args_list)
assert "Exception:foobar" in str(mock_log_error.call_args_list)
assert ret is False
@patch("qmk_cli.git.subprocess.Popen")
def test_git_clone_logs_output(mock_popen, capsys):
type(mock_popen().__enter__()).returncode = PropertyMock(return_value=0)
type(mock_popen().__enter__()).stdout = PropertyMock(return_value=['asdf'])
ret = qmk_cli.git.git_clone('/tmp', 'https://github.com/qmk/qmk_firmware', 'master')
captured = capsys.readouterr().out
assert 'asdf' in captured
assert ret is True
@patch("qmk_cli.git.subprocess.Popen")
def test_git_clone_captures_exit_code(mock_popen):
type(mock_popen().__enter__()).returncode = PropertyMock(return_value=1)
ret = qmk_cli.git.git_clone('/tmp', 'https://github.com/qmk/qmk_firmware', 'master')
assert ret is False
@patch("qmk_cli.git.subprocess.Popen", side_effect=Exception("foobar"))
@patch("qmk_cli.git.cli.log.error")
def test_git_set_upstream_except(mock_log_error, mock_popen):
ret = qmk_cli.git.git_set_upstream('/tmp')
assert "Could not run" in str(mock_log_error.call_args_list)
assert "Exception:foobar" in str(mock_log_error.call_args_list)
assert ret is False
@patch("qmk_cli.git.subprocess.Popen")
def test_git_set_upstream_logs_output(mock_popen, capsys):
type(mock_popen().__enter__()).returncode = PropertyMock(return_value=0)
type(mock_popen().__enter__()).stdout = PropertyMock(return_value=['asdf'])
ret = qmk_cli.git.git_set_upstream('/tmp')
captured = capsys.readouterr().out
assert 'asdf' in captured
assert ret is True
@patch("qmk_cli.git.subprocess.Popen")
def test_git_set_upstream_captures_exit_code(mock_popen):
type(mock_popen().__enter__()).returncode = PropertyMock(return_value=1)
ret = qmk_cli.git.git_set_upstream('/tmp')
assert ret is False
@patch.object(qmk_cli.git, 'git_clone')
@patch.object(qmk_cli.git, 'git_set_upstream')
def test_git_clone_fork_fail(git_set_upstream, git_clone, temp_directory):
git_clone.return_value = False
git_set_upstream.return_value = False
ret = qmk_cli.git.git_clone_fork(temp_directory.as_posix(), 'https://github.com', 'qmk/qmk_firmware', 'master', False)
assert ret is False
@patch.object(qmk_cli.git, 'git_clone')
@patch.object(qmk_cli.git, 'git_set_upstream')
def test_git_clone_fork_force(git_set_upstream, git_clone, temp_directory):
(temp_directory / 'asdf').touch()
git_clone.return_value = True
git_set_upstream.return_value = True
ret = qmk_cli.git.git_clone_fork(temp_directory.as_posix(), 'https://github.com', 'qmk/qmk_firmware', 'master', True)
assert ret is True
assert (temp_directory / 'asdf').exists() is False
@pytest.mark.integration
def test_git_clone(temp_directory):
qmk_firmware = temp_directory / 'qmk_firmware'
ret = qmk_cli.git.git_clone(qmk_firmware.as_posix(), 'https://github.com/qmk/qmk_firmware', 'master')
from qmk_cli.helpers import is_qmk_firmware
assert is_qmk_firmware(qmk_firmware) is True
assert ret is True
@pytest.mark.integration
def test_git_clone_fork(temp_directory):
qmk_firmware = temp_directory / 'qmk_firmware'
qmk_firmware.mkdir()
(qmk_firmware / 'asdf').touch()
ret = qmk_cli.git.git_clone_fork(qmk_firmware.as_posix(), 'https://github.com', 'qmk/qmk_firmware', 'master', True)
from qmk_cli.helpers import is_qmk_firmware
assert is_qmk_firmware(qmk_firmware) is True
assert 'https://github.com/qmk/qmk_firmware' in subprocess.run(['git', '-C', qmk_firmware.as_posix(), 'remote', 'get-url', 'upstream'], capture_output=True, text=True).stdout
assert ret is True
+246
View File
@@ -0,0 +1,246 @@
import os
import stat
import pytest
from pathlib import Path
from unittest.mock import patch, PropertyMock
import qmk_cli.helpers
@pytest.fixture(autouse=True)
def reset_env():
cur_dir = os.getcwd()
yield cur_dir
os.chdir(cur_dir)
qmk_cli.helpers.find_qmk_firmware.cache_clear()
qmk_cli.helpers.in_qmk_firmware.cache_clear()
qmk_cli.helpers.find_qmk_userspace.cache_clear()
qmk_cli.helpers.in_qmk_userspace.cache_clear()
def test_abspath(temp_directory):
tmp = temp_directory.absolute()
ret = qmk_cli.helpers.AbsPath(tmp)
assert ret.samefile(tmp)
def test_abspath_str(temp_directory):
tmp = temp_directory.absolute().as_posix()
ret = qmk_cli.helpers.AbsPath(tmp)
assert ret.samefile(tmp)
def test_abspath_rel(temp_directory):
with patch.dict('os.environ', {'ORIG_CWD': temp_directory.as_posix()}, clear=True):
tmp = './asdf'
ret = qmk_cli.helpers.AbsPath(tmp)
assert ret.as_posix() == (temp_directory / 'asdf').as_posix()
def test_rmtree(temp_directory):
tmp = temp_directory / 'asdf.txt'
tmp.touch()
qmk_cli.helpers.rmtree(temp_directory)
assert tmp.exists() is False
@pytest.mark.skipif(os.name != "nt", reason="Only triggers issue on windows")
def test_rmtree_readonly(temp_directory):
tmp = temp_directory / 'asdf.txt'
tmp.touch()
os.chmod(tmp, stat.S_IREAD)
qmk_cli.helpers.rmtree(temp_directory)
assert tmp.exists() is False
def test_is_qmk_firmware(temp_directory):
(temp_directory / 'quantum').mkdir(parents=True)
(temp_directory / 'lib/python/qmk/cli').mkdir(parents=True)
(temp_directory / 'requirements.txt').touch()
(temp_directory / 'requirements-dev.txt').touch()
(temp_directory / 'lib/python/qmk/cli/__init__.py').touch()
assert qmk_cli.helpers.is_qmk_firmware(temp_directory) is True
def test_is_qmk_firmware_partially_missing(temp_directory):
(temp_directory / 'lib/python/qmk/cli').mkdir(parents=True)
(temp_directory / 'lib/python/qmk/cli/__init__.py').touch()
assert qmk_cli.helpers.is_qmk_firmware(temp_directory) is False
def test_find_qmk_firmware(temp_directory):
(temp_directory / 'quantum').mkdir(parents=True)
(temp_directory / 'lib/python/qmk/cli').mkdir(parents=True)
(temp_directory / 'requirements.txt').touch()
(temp_directory / 'requirements-dev.txt').touch()
(temp_directory / 'lib/python/qmk/cli/__init__.py').touch()
os.chdir(temp_directory)
assert qmk_cli.helpers.find_qmk_firmware().as_posix() == temp_directory.as_posix()
def test_find_qmk_firmware_env(temp_directory):
with patch.dict('os.environ', {'QMK_HOME': temp_directory.as_posix()}, clear=True):
assert qmk_cli.helpers.find_qmk_firmware().as_posix() == temp_directory.as_posix()
def test_find_qmk_firmware_env_missing(temp_directory):
with patch.dict('os.environ', {'QMK_HOME': (temp_directory / 'asdf').as_posix()}, clear=True):
assert qmk_cli.helpers.find_qmk_firmware().as_posix() == (temp_directory / 'asdf').as_posix()
def test_find_qmk_firmware_config(temp_directory):
with patch.object(qmk_cli.helpers, 'cli') as cli:
type(cli.config.user).qmk_home = PropertyMock(return_value=temp_directory.as_posix())
assert qmk_cli.helpers.find_qmk_firmware().as_posix() == temp_directory.as_posix()
def test_find_qmk_firmware_config_user():
with patch.object(qmk_cli.helpers, 'cli') as cli:
type(cli.config.user).qmk_home = PropertyMock(return_value='~/asdf')
assert qmk_cli.helpers.find_qmk_firmware().as_posix() == (Path.home() / 'asdf').as_posix()
def test_find_qmk_firmware_default(temp_directory):
with patch('pathlib.Path.home') as home:
home.return_value = temp_directory
assert qmk_cli.helpers.find_qmk_firmware().as_posix() == (temp_directory / 'qmk_firmware').as_posix()
def test_in_qmk_firmware(temp_directory):
(temp_directory / 'quantum').mkdir(parents=True)
(temp_directory / 'lib/python/qmk/cli').mkdir(parents=True)
(temp_directory / 'requirements.txt').touch()
(temp_directory / 'requirements-dev.txt').touch()
(temp_directory / 'lib/python/qmk/cli/__init__.py').touch()
os.chdir(temp_directory)
assert qmk_cli.helpers.in_qmk_firmware().as_posix() == temp_directory.as_posix()
def test_in_qmk_firmware_sub(temp_directory):
(temp_directory / 'quantum').mkdir(parents=True)
(temp_directory / 'lib/python/qmk/cli').mkdir(parents=True)
(temp_directory / 'requirements.txt').touch()
(temp_directory / 'requirements-dev.txt').touch()
(temp_directory / 'lib/python/qmk/cli/__init__.py').touch()
os.chdir(temp_directory / 'quantum')
assert qmk_cli.helpers.in_qmk_firmware().as_posix() == temp_directory.as_posix()
def test_in_qmk_firmware_sub_sub(temp_directory):
(temp_directory / 'quantum').mkdir(parents=True)
(temp_directory / 'lib/python/qmk/cli').mkdir(parents=True)
(temp_directory / 'requirements.txt').touch()
(temp_directory / 'requirements-dev.txt').touch()
(temp_directory / 'lib/python/qmk/cli/__init__.py').touch()
os.chdir(temp_directory / 'lib' / 'python')
assert qmk_cli.helpers.in_qmk_firmware().as_posix() == temp_directory.as_posix()
def test_in_qmk_firmware_invalid(temp_directory):
os.chdir(temp_directory)
assert qmk_cli.helpers.in_qmk_firmware() is None
def test_is_qmk_userspace(temp_directory):
(temp_directory / 'qmk.json').write_text('{"userspace_version": 2}')
assert qmk_cli.helpers.is_qmk_userspace(temp_directory) is True
def test_is_qmk_userspace_missing(temp_directory):
assert qmk_cli.helpers.is_qmk_userspace(temp_directory) is False
def test_is_qmk_userspace_invalid(temp_directory):
(temp_directory / 'qmk.json').write_text('asdf')
assert qmk_cli.helpers.is_qmk_userspace(temp_directory) is False
def test_is_qmk_userspace_empty(temp_directory):
(temp_directory / 'qmk.json').touch()
assert qmk_cli.helpers.is_qmk_userspace(temp_directory) is False
def test_find_qmk_userspace(temp_directory):
(temp_directory / 'qmk.json').write_text('{"userspace_version": 2}')
os.chdir(temp_directory)
assert qmk_cli.helpers.find_qmk_userspace().as_posix() == temp_directory.as_posix()
def test_find_qmk_userspace_env(temp_directory):
with patch.dict('os.environ', {'QMK_USERSPACE': temp_directory.as_posix()}, clear=True):
assert qmk_cli.helpers.find_qmk_userspace().as_posix() == temp_directory.as_posix()
def test_find_qmk_userspace_env_missing(temp_directory):
with patch.dict('os.environ', {'QMK_USERSPACE': (temp_directory / 'asdf').as_posix()}, clear=True):
assert qmk_cli.helpers.find_qmk_userspace().as_posix() == (temp_directory / 'asdf').as_posix()
def test_find_qmk_userspace_config(temp_directory):
with patch.object(qmk_cli.helpers, 'cli') as cli:
type(cli.config.user).overlay_dir = PropertyMock(return_value=temp_directory.as_posix())
assert qmk_cli.helpers.find_qmk_userspace().as_posix() == temp_directory.as_posix()
def test_find_qmk_userspace_config_user():
with patch.object(qmk_cli.helpers, 'cli') as cli:
type(cli.config.user).overlay_dir = PropertyMock(return_value='~/asdf')
assert qmk_cli.helpers.find_qmk_userspace().as_posix() == (Path.home() / 'asdf').as_posix()
def test_find_qmk_userspace_default(temp_directory):
with patch('pathlib.Path.home') as home:
home.return_value = temp_directory
assert qmk_cli.helpers.find_qmk_userspace().as_posix() == (temp_directory / 'qmk_userspace').as_posix()
def test_in_qmk_userspace(temp_directory):
(temp_directory / 'qmk.json').write_text('{"userspace_version": 2}')
os.chdir(temp_directory)
assert qmk_cli.helpers.in_qmk_userspace().as_posix() == temp_directory.as_posix()
def test_in_qmk_userspace_sub(temp_directory):
(temp_directory / 'qmk.json').write_text('{"userspace_version": 2}')
(temp_directory / 'keymaps' / 'test').mkdir(parents=True)
os.chdir(temp_directory / 'keymaps')
assert qmk_cli.helpers.in_qmk_userspace().as_posix() == temp_directory.as_posix()
def test_in_qmk_userspace_sub_sub(temp_directory):
(temp_directory / 'qmk.json').write_text('{"userspace_version": 2}')
(temp_directory / 'keymaps' / 'test').mkdir(parents=True)
os.chdir(temp_directory / 'keymaps' / 'test')
assert qmk_cli.helpers.in_qmk_userspace().as_posix() == temp_directory.as_posix()
def test_in_qmk_userspace_invalid(temp_directory):
os.chdir(temp_directory)
assert qmk_cli.helpers.in_qmk_userspace() is None