summaryrefslogtreecommitdiff
path: root/util
diff options
context:
space:
mode:
authorDrashna Jael're <drashna@live.com>2021-10-11 20:36:47 -0700
committerDrashna Jael're <drashna@live.com>2021-10-11 20:36:47 -0700
commitb34675555cbd9a71a797a7ebc2148cbf2e8f0efc (patch)
tree2d701310ccd3fc2c603d63536ab4a3c1d9b9381b /util
parentbcddde8738dbba48c548f1e3f12a10bbf60a65d8 (diff)
parentd9e077468ab3446cbd7306a453a73dad2c1403e8 (diff)
Merge commit 'd9e077468ab3446cbd7306a453a73dad2c1403e8' into firmware_21
Diffstat (limited to 'util')
-rw-r--r--util/bootloader_at90usb128_1.0.1.hex2
-rw-r--r--util/bootloader_at90usb64_1.0.0.hex2
-rwxr-xr-xutil/chibios_conf_updater.sh2
-rwxr-xr-xutil/docker_build.sh2
-rwxr-xr-xutil/generate_internal_docs.sh2
-rwxr-xr-xutil/install/arch.sh2
-rwxr-xr-xutil/install/debian.sh2
-rwxr-xr-xutil/install/fedora.sh2
-rwxr-xr-xutil/install/freebsd.sh2
-rwxr-xr-xutil/install/gentoo.sh2
-rwxr-xr-xutil/install/linux_shared.sh2
-rwxr-xr-xutil/install/macos.sh4
-rwxr-xr-xutil/install/msys2.sh2
-rwxr-xr-xutil/install/slackware.sh2
-rwxr-xr-xutil/install/solus.sh2
-rwxr-xr-xutil/install/void.sh2
-rwxr-xr-xutil/new_keyboard.sh14
-rw-r--r--util/nix/poetry.lock468
-rw-r--r--util/nix/pyproject.toml36
-rw-r--r--util/nix/sources.json38
-rw-r--r--util/nix/sources.nix174
-rwxr-xr-xutil/qmk_install.sh4
-rw-r--r--util/reset.eep9
-rwxr-xr-xutil/rules_cleaner.sh2
-rwxr-xr-xutil/stm32eeprom_parser.py316
-rwxr-xr-xutil/travis_utils.sh25
-rw-r--r--util/udev/50-qmk.rules6
-rwxr-xr-xutil/uf2conv.py8
-rwxr-xr-xutil/update_chibios_mirror.sh92
-rw-r--r--util/vagrant/Dockerfile2
-rw-r--r--util/vagrant/readme.md2
31 files changed, 1175 insertions, 55 deletions
diff --git a/util/bootloader_at90usb128_1.0.1.hex b/util/bootloader_at90usb128_1.0.1.hex
index 90491a82a6..5ecbed2880 100644
--- a/util/bootloader_at90usb128_1.0.1.hex
+++ b/util/bootloader_at90usb128_1.0.1.hex
@@ -269,7 +269,7 @@
:10F11A002A2F0C946CF00E9451F780E090E0A0E056
:10F12A00B0E08C019D010E94BEF780509F4FAF4F07
:10F13A00BF4F8F3F0FED900701E0A007B80788F394
-:10F14A00E4E00C9462F712010020FE010020EB03B8
+:10F14A00E4E00C9462F712010002FF010020EB03D5
:10F15A00FB2F0000010203010902120001010080D5
:10F16A00320904000000000000000C0341005400B2
:10F17A004D0045004C001E03410054003900300088
diff --git a/util/bootloader_at90usb64_1.0.0.hex b/util/bootloader_at90usb64_1.0.0.hex
index 69dd45bbd6..5b443d7195 100644
--- a/util/bootloader_at90usb64_1.0.0.hex
+++ b/util/bootloader_at90usb64_1.0.0.hex
@@ -1,7 +1,7 @@
:020000020000FC
:04F000000C94B97E35
:04F028000C94C77D00
-:10F08B0012010020FE010020EB03F92F000000000D
+:10F08B0012010002FF010020EB03F92F000000002A
:10F09B000001090212000101008032090400000086
:04F0AB000000000061
:10F0B0000000827E0800717E747E767E787E7A7E85
diff --git a/util/chibios_conf_updater.sh b/util/chibios_conf_updater.sh
index 70bd80da1e..5ba8aa677b 100755
--- a/util/chibios_conf_updater.sh
+++ b/util/chibios_conf_updater.sh
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
set -eEuo pipefail
umask 022
diff --git a/util/docker_build.sh b/util/docker_build.sh
index 2c2a26e776..368b0f13fc 100755
--- a/util/docker_build.sh
+++ b/util/docker_build.sh
@@ -81,5 +81,5 @@ fi
-e ALT_GET_KEYBOARDS=true \
-e SKIP_GIT="$SKIP_GIT" \
-e MAKEFLAGS="$MAKEFLAGS" \
- qmkfm/base_container \
+ qmkfm/qmk_cli \
make "$keyboard${keymap:+:$keymap}${target:+:$target}"
diff --git a/util/generate_internal_docs.sh b/util/generate_internal_docs.sh
index bfee797d3a..b107a37ad6 100755
--- a/util/generate_internal_docs.sh
+++ b/util/generate_internal_docs.sh
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
set -x
diff --git a/util/install/arch.sh b/util/install/arch.sh
index eac4ad64ef..bef98ac37f 100755
--- a/util/install/arch.sh
+++ b/util/install/arch.sh
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
_qmk_install() {
echo "Installing dependencies"
diff --git a/util/install/debian.sh b/util/install/debian.sh
index 9e12996976..57588e371a 100755
--- a/util/install/debian.sh
+++ b/util/install/debian.sh
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
DEBIAN_FRONTEND=noninteractive
DEBCONF_NONINTERACTIVE_SEEN=true
diff --git a/util/install/fedora.sh b/util/install/fedora.sh
index 3f9695356c..e123447d3f 100755
--- a/util/install/fedora.sh
+++ b/util/install/fedora.sh
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
_qmk_install() {
echo "Installing dependencies"
diff --git a/util/install/freebsd.sh b/util/install/freebsd.sh
index d9399a5de9..595911969d 100755
--- a/util/install/freebsd.sh
+++ b/util/install/freebsd.sh
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
_qmk_install_prepare() {
sudo pkg update $SKIP_PROMPT
diff --git a/util/install/gentoo.sh b/util/install/gentoo.sh
index 604d07bf84..b031fc7629 100755
--- a/util/install/gentoo.sh
+++ b/util/install/gentoo.sh
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
_qmk_install_prepare() {
echo "This script will make a USE change in order to ensure that that QMK works on your system."
diff --git a/util/install/linux_shared.sh b/util/install/linux_shared.sh
index cb81e8611f..e060f425f5 100755
--- a/util/install/linux_shared.sh
+++ b/util/install/linux_shared.sh
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
# For those distros that do not package bootloadHID
_qmk_install_bootloadhid() {
diff --git a/util/install/macos.sh b/util/install/macos.sh
index 4b87217ba0..870b4bec94 100755
--- a/util/install/macos.sh
+++ b/util/install/macos.sh
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
_qmk_install_prepare() {
echo "Checking Homebrew installation"
@@ -9,7 +9,7 @@ _qmk_install_prepare() {
return 1
fi
- brew update && brew upgrade --ignore-pinned
+ brew update && brew upgrade --formulae --ignore-pinned
}
_qmk_install() {
diff --git a/util/install/msys2.sh b/util/install/msys2.sh
index b027ff53d2..203f8eff0c 100755
--- a/util/install/msys2.sh
+++ b/util/install/msys2.sh
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
_qmk_install_prepare() {
pacman -Syu $MSYS2_CONFIRM
diff --git a/util/install/slackware.sh b/util/install/slackware.sh
index d73303159d..df4d073e7b 100755
--- a/util/install/slackware.sh
+++ b/util/install/slackware.sh
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
_qmk_install_prepare() {
echo "Before you continue, please ensure that your user is added to sudoers and that sboinstall is configured."
diff --git a/util/install/solus.sh b/util/install/solus.sh
index 5633f7039c..fad0605cf6 100755
--- a/util/install/solus.sh
+++ b/util/install/solus.sh
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
_qmk_install_prepare() {
sudo eopkg -y update-repo
diff --git a/util/install/void.sh b/util/install/void.sh
index c49c3ef63f..6aeb8e00ae 100755
--- a/util/install/void.sh
+++ b/util/install/void.sh
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
_qmk_install() {
echo "Installing dependencies"
diff --git a/util/new_keyboard.sh b/util/new_keyboard.sh
index cf3339f9a7..62e8cb9e13 100755
--- a/util/new_keyboard.sh
+++ b/util/new_keyboard.sh
@@ -1,7 +1,7 @@
-#!/bin/bash
+#!/usr/bin/env bash
# This script generates a new keyboard directory under keyboards/,
-# and copies the template files from quantum/template/ into it.
+# and copies the template files from data/templates/ into it.
# Print an error message with the word "ERROR" in red.
echo_error() {
@@ -35,11 +35,11 @@ copy_templates() {
mkdir -p "$keyboard_dir"
echo -n "Copying base template files..."
- cp -r "quantum/template/base/." "${keyboard_dir}"
+ cp -r "data/templates/base/." "${keyboard_dir}"
echo " done"
echo -n "Copying $keyboard_type template files..."
- cp -r "quantum/template/${keyboard_type}/." "${keyboard_dir}"
+ cp -r "data/templates/${keyboard_type}/." "${keyboard_dir}"
echo " done"
echo -n "Renaming keyboard files..."
@@ -129,6 +129,12 @@ if [ ! -d "quantum" ]; then
exit 1
fi
+echo_bold "########################################"
+echo_bold "# NOTICE #"
+echo_bold "# This script has been deprecated. #"
+echo_bold "# Please use qmk new-keyboard instead. #"
+echo_bold "########################################"
+echo
echo_bold "Generating a new QMK keyboard directory"
echo
diff --git a/util/nix/poetry.lock b/util/nix/poetry.lock
new file mode 100644
index 0000000000..9bb0f64deb
--- /dev/null
+++ b/util/nix/poetry.lock
@@ -0,0 +1,468 @@
+[[package]]
+name = "appdirs"
+version = "1.4.4"
+description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"."
+category = "main"
+optional = false
+python-versions = "*"
+
+[[package]]
+name = "argcomplete"
+version = "1.12.3"
+description = "Bash tab completion for argparse"
+category = "main"
+optional = false
+python-versions = "*"
+
+[package.extras]
+test = ["coverage", "flake8", "pexpect", "wheel"]
+
+[[package]]
+name = "attrs"
+version = "21.2.0"
+description = "Classes Without Boilerplate"
+category = "main"
+optional = false
+python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
+
+[package.extras]
+dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "furo", "sphinx", "sphinx-notfound-page", "pre-commit"]
+docs = ["furo", "sphinx", "zope.interface", "sphinx-notfound-page"]
+tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface"]
+tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins"]
+
+[[package]]
+name = "colorama"
+version = "0.4.4"
+description = "Cross-platform colored terminal text."
+category = "main"
+optional = false
+python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
+
+[[package]]
+name = "coverage"
+version = "5.5"
+description = "Code coverage measurement for Python"
+category = "dev"
+optional = false
+python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4"
+
+[package.extras]
+toml = ["toml"]
+
+[[package]]
+name = "flake8"
+version = "3.9.2"
+description = "the modular source code checker: pep8 pyflakes and co"
+category = "dev"
+optional = false
+python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7"
+
+[package.dependencies]
+mccabe = ">=0.6.0,<0.7.0"
+pycodestyle = ">=2.7.0,<2.8.0"
+pyflakes = ">=2.3.0,<2.4.0"
+
+[[package]]
+name = "flake8-polyfill"
+version = "1.0.2"
+description = "Polyfill package for Flake8 plugins"
+category = "dev"
+optional = false
+python-versions = "*"
+
+[package.dependencies]
+flake8 = "*"
+
+[[package]]
+name = "halo"
+version = "0.0.31"
+description = "Beautiful terminal spinners in Python"
+category = "main"
+optional = false
+python-versions = ">=3.4"
+
+[package.dependencies]
+colorama = ">=0.3.9"
+log-symbols = ">=0.0.14"
+six = ">=1.12.0"
+spinners = ">=0.0.24"
+termcolor = ">=1.1.0"
+
+[package.extras]
+ipython = ["IPython (==5.7.0)", "ipywidgets (==7.1.0)"]
+
+[[package]]
+name = "hid"
+version = "1.0.4"
+description = "ctypes bindings for hidapi"
+category = "main"
+optional = false
+python-versions = "*"
+
+[[package]]
+name = "hjson"
+version = "3.0.2"
+description = "Hjson, a user interface for JSON."
+category = "main"
+optional = false
+python-versions = "*"
+
+[[package]]
+name = "jsonschema"
+version = "3.2.0"
+description = "An implementation of JSON Schema validation for Python"
+category = "main"
+optional = false
+python-versions = "*"
+
+[package.dependencies]
+attrs = ">=17.4.0"
+pyrsistent = ">=0.14.0"
+six = ">=1.11.0"
+
+[package.extras]
+format = ["idna", "jsonpointer (>1.13)", "rfc3987", "strict-rfc3339", "webcolors"]
+format_nongpl = ["idna", "jsonpointer (>1.13)", "webcolors", "rfc3986-validator (>0.1.0)", "rfc3339-validator"]
+
+[[package]]
+name = "log-symbols"
+version = "0.0.14"
+description = "Colored symbols for various log levels for Python"
+category = "main"
+optional = false
+python-versions = "*"
+
+[package.dependencies]
+colorama = ">=0.3.9"
+
+[[package]]
+name = "mccabe"
+version = "0.6.1"
+description = "McCabe checker, plugin for flake8"
+category = "dev"
+optional = false
+python-versions = "*"
+
+[[package]]
+name = "milc"
+version = "1.6.2"
+description = "Opinionated Batteries-Included Python 3 CLI Framework."
+category = "main"
+optional = false
+python-versions = "*"
+
+[package.dependencies]
+appdirs = "*"
+argcomplete = "*"
+colorama = "*"
+halo = "*"
+spinners = "*"
+
+[[package]]
+name = "nose2"
+version = "0.10.0"
+description = "unittest2 with plugins, the succesor to nose"
+category = "dev"
+optional = false
+python-versions = "*"
+
+[package.dependencies]
+coverage = ">=4.4.1"
+six = ">=1.7"
+
+[package.extras]
+coverage_plugin = ["coverage (>=4.4.1)"]
+dev = ["Sphinx (>=1.6.5)", "sphinx-rtd-theme", "mock", "coverage"]
+
+[[package]]
+name = "pep8-naming"
+version = "0.12.1"
+description = "Check PEP-8 naming conventions, plugin for flake8"
+category = "dev"
+optional = false
+python-versions = "*"
+
+[package.dependencies]
+flake8 = ">=3.9.1"
+flake8-polyfill = ">=1.0.2,<2"
+
+[[package]]
+name = "pycodestyle"
+version = "2.7.0"
+description = "Python style guide checker"
+category = "dev"
+optional = false
+python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
+
+[[package]]
+name = "pyflakes"
+version = "2.3.1"
+description = "passive checker of Python programs"
+category = "dev"
+optional = false
+python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
+
+[[package]]
+name = "pygments"
+version = "2.10.0"
+description = "Pygments is a syntax highlighting package written in Python."
+category = "main"
+optional = false
+python-versions = ">=3.5"
+
+[[package]]
+name = "pyrsistent"
+version = "0.18.0"
+description = "Persistent/Functional/Immutable data structures"
+category = "main"
+optional = false
+python-versions = ">=3.6"
+
+[[package]]
+name = "pyusb"
+version = "1.2.1"
+description = "Python USB access module"
+category = "main"
+optional = false
+python-versions = ">=3.6.0"
+
+[[package]]
+name = "qmk"
+version = "1.0.0"
+description = "A program to help users work with QMK Firmware."
+category = "main"
+optional = false
+python-versions = "*"
+
+[package.dependencies]
+hid = "*"
+hjson = "*"
+jsonschema = ">=3"
+milc = ">=1.4.2"
+pygments = "*"
+pyusb = "*"
+qmk-dotty-dict = "*"
+
+[[package]]
+name = "qmk-dotty-dict"
+version = "1.3.0.post1"
+description = "Dictionary wrapper for quick access to deeply nested keys."
+category = "main"
+optional = false
+python-versions = "*"
+
+[[package]]
+name = "six"
+version = "1.16.0"
+description = "Python 2 and 3 compatibility utilities"
+category = "main"
+optional = false
+python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*"
+
+[[package]]
+name = "spinners"
+version = "0.0.24"
+description = "Spinners for terminals"
+category = "main"
+optional = false
+python-versions = "*"
+
+[[package]]
+name = "termcolor"
+version = "1.1.0"
+description = "ANSII Color formatting for output in terminal."
+category = "main"
+optional = false
+python-versions = "*"
+
+[[package]]
+name = "yapf"
+version = "0.31.0"
+description = "A formatter for Python code."
+category = "dev"
+optional = false
+python-versions = "*"
+
+[metadata]
+lock-version = "1.1"
+python-versions = "^3.8"
+content-hash = "468ae51aaddfe2ce62938f131c688bbc447e41608d4dd7d30db36391c38bda20"
+
+[metadata.files]
+appdirs = [
+ {file = "appdirs-1.4.4-py2.py3-none-any.whl", hash = "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128"},
+ {file = "appdirs-1.4.4.tar.gz", hash = "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41"},
+]
+argcomplete = [
+ {file = "argcomplete-1.12.3-py2.py3-none-any.whl", hash = "sha256:291f0beca7fd49ce285d2f10e4c1c77e9460cf823eef2de54df0c0fec88b0d81"},
+ {file = "argcomplete-1.12.3.tar.gz", hash = "sha256:2c7dbffd8c045ea534921e63b0be6fe65e88599990d8dc408ac8c542b72a5445"},
+]
+attrs = [
+ {file = "attrs-21.2.0-py2.py3-none-any.whl", hash = "sha256:149e90d6d8ac20db7a955ad60cf0e6881a3f20d37096140088356da6c716b0b1"},
+ {file = "attrs-21.2.0.tar.gz", hash = "sha256:ef6aaac3ca6cd92904cdd0d83f629a15f18053ec84e6432106f7a4d04ae4f5fb"},
+]
+colorama = [
+ {file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"},
+ {file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"},
+]
+coverage = [
+ {file = "coverage-5.5-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:b6d534e4b2ab35c9f93f46229363e17f63c53ad01330df9f2d6bd1187e5eaacf"},
+ {file = "coverage-5.5-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:b7895207b4c843c76a25ab8c1e866261bcfe27bfaa20c192de5190121770672b"},
+ {file = "coverage-5.5-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:c2723d347ab06e7ddad1a58b2a821218239249a9e4365eaff6649d31180c1669"},
+ {file = "coverage-5.5-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:900fbf7759501bc7807fd6638c947d7a831fc9fdf742dc10f02956ff7220fa90"},
+ {file = "coverage-5.5-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:004d1880bed2d97151facef49f08e255a20ceb6f9432df75f4eef018fdd5a78c"},
+ {file = "coverage-5.5-cp27-cp27m-win32.whl", hash = "sha256:06191eb60f8d8a5bc046f3799f8a07a2d7aefb9504b0209aff0b47298333302a"},
+ {file = "coverage-5.5-cp27-cp27m-win_amd64.whl", hash = "sha256:7501140f755b725495941b43347ba8a2777407fc7f250d4f5a7d2a1050ba8e82"},
+ {file = "coverage-5.5-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:372da284cfd642d8e08ef606917846fa2ee350f64994bebfbd3afb0040436905"},
+ {file = "coverage-5.5-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:8963a499849a1fc54b35b1c9f162f4108017b2e6db2c46c1bed93a72262ed083"},
+ {file = "coverage-5.5-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:869a64f53488f40fa5b5b9dcb9e9b2962a66a87dab37790f3fcfb5144b996ef5"},
+ {file = "coverage-5.5-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:4a7697d8cb0f27399b0e393c0b90f0f1e40c82023ea4d45d22bce7032a5d7b81"},
+ {file = "coverage-5.5-cp310-cp310-macosx_10_14_x86_64.whl", hash = "sha256:8d0a0725ad7c1a0bcd8d1b437e191107d457e2ec1084b9f190630a4fb1af78e6"},
+ {file = "coverage-5.5-cp310-cp310-manylinux1_x86_64.whl", hash = "sha256:51cb9476a3987c8967ebab3f0fe144819781fca264f57f89760037a2ea191cb0"},
+ {file = "coverage-5.5-cp310-cp310-win_amd64.whl", hash = "sha256:c0891a6a97b09c1f3e073a890514d5012eb256845c451bd48f7968ef939bf4ae"},
+ {file = "coverage-5.5-cp35-cp35m-macosx_10_9_x86_64.whl", hash = "sha256:3487286bc29a5aa4b93a072e9592f22254291ce96a9fbc5251f566b6b7343cdb"},
+ {file = "coverage-5.5-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:deee1077aae10d8fa88cb02c845cfba9b62c55e1183f52f6ae6a2df6a2187160"},
+ {file = "coverage-5.5-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:f11642dddbb0253cc8853254301b51390ba0081750a8ac03f20ea8103f0c56b6"},
+ {file = "coverage-5.5-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:6c90e11318f0d3c436a42409f2749ee1a115cd8b067d7f14c148f1ce5574d701"},
+ {file = "coverage-5.5-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:30c77c1dc9f253283e34c27935fded5015f7d1abe83bc7821680ac444eaf7793"},
+ {file = "coverage-5.5-cp35-cp35m-win32.whl", hash = "sha256:9a1ef3b66e38ef8618ce5fdc7bea3d9f45f3624e2a66295eea5e57966c85909e"},
+ {file = "coverage-5.5-cp35-cp35m-win_amd64.whl", hash = "sha256:972c85d205b51e30e59525694670de6a8a89691186012535f9d7dbaa230e42c3"},
+ {file = "coverage-5.5-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:af0e781009aaf59e25c5a678122391cb0f345ac0ec272c7961dc5455e1c40066"},
+ {file = "coverage-5.5-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:74d881fc777ebb11c63736622b60cb9e4aee5cace591ce274fb69e582a12a61a"},
+ {file = "coverage-5.5-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:92b017ce34b68a7d67bd6d117e6d443a9bf63a2ecf8567bb3d8c6c7bc5014465"},
+ {file = "coverage-5.5-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:d636598c8305e1f90b439dbf4f66437de4a5e3c31fdf47ad29542478c8508bbb"},
+ {file = "coverage-5.5-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:41179b8a845742d1eb60449bdb2992196e211341818565abded11cfa90efb821"},
+ {file = "coverage-5.5-cp36-cp36m-win32.whl", hash = "sha256:040af6c32813fa3eae5305d53f18875bedd079960822ef8ec067a66dd8afcd45"},
+ {file = "coverage-5.5-cp36-cp36m-win_amd64.whl", hash = "sha256:5fec2d43a2cc6965edc0bb9e83e1e4b557f76f843a77a2496cbe719583ce8184"},
+ {file = "coverage-5.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:18ba8bbede96a2c3dde7b868de9dcbd55670690af0988713f0603f037848418a"},
+ {file = "coverage-5.5-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:2910f4d36a6a9b4214bb7038d537f015346f413a975d57ca6b43bf23d6563b53"},
+ {file = "coverage-5.5-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:f0b278ce10936db1a37e6954e15a3730bea96a0997c26d7fee88e6c396c2086d"},
+ {file = "coverage-5.5-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:796c9c3c79747146ebd278dbe1e5c5c05dd6b10cc3bcb8389dfdf844f3ead638"},
+ {file = "coverage-5.5-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:53194af30d5bad77fcba80e23a1441c71abfb3e01192034f8246e0d8f99528f3"},
+ {file = "coverage-5.5-cp37-cp37m-win32.whl", hash = "sha256:184a47bbe0aa6400ed2d41d8e9ed868b8205046518c52464fde713ea06e3a74a"},
+ {file = "coverage-5.5-cp37-cp37m-win_amd64.whl", hash = "sha256:2949cad1c5208b8298d5686d5a85b66aae46d73eec2c3e08c817dd3513e5848a"},
+ {file = "coverage-5.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:217658ec7187497e3f3ebd901afdca1af062b42cfe3e0dafea4cced3983739f6"},
+ {file = "coverage-5.5-cp38-cp38-manylinux1_i686.whl", hash = "sha256:1aa846f56c3d49205c952d8318e76ccc2ae23303351d9270ab220004c580cfe2"},
+ {file = "coverage-5.5-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:24d4a7de75446be83244eabbff746d66b9240ae020ced65d060815fac3423759"},
+ {file = "coverage-5.5-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:d1f8bf7b90ba55699b3a5e44930e93ff0189aa27186e96071fac7dd0d06a1873"},
+ {file = "coverage-5.5-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:970284a88b99673ccb2e4e334cfb38a10aab7cd44f7457564d11898a74b62d0a"},
+ {file = "coverage-5.5-cp38-cp38-win32.whl", hash = "sha256:01d84219b5cdbfc8122223b39a954820929497a1cb1422824bb86b07b74594b6"},
+ {file = "coverage-5.5-cp38-cp38-win_amd64.whl", hash = "sha256:2e0d881ad471768bf6e6c2bf905d183543f10098e3b3640fc029509530091502"},
+ {file = "coverage-5.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d1f9ce122f83b2305592c11d64f181b87153fc2c2bbd3bb4a3dde8303cfb1a6b"},
+ {file = "coverage-5.5-cp39-cp39-manylinux1_i686.whl", hash = "sha256:13c4ee887eca0f4c5a247b75398d4114c37882658300e153113dafb1d76de529"},
+ {file = "coverage-5.5-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:52596d3d0e8bdf3af43db3e9ba8dcdaac724ba7b5ca3f6358529d56f7a166f8b"},
+ {file = "coverage-5.5-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:2cafbbb3af0733db200c9b5f798d18953b1a304d3f86a938367de1567f4b5bff"},
+ {file = "coverage-5.5-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:44d654437b8ddd9eee7d1eaee28b7219bec228520ff809af170488fd2fed3e2b"},
+ {file = "coverage-5.5-cp39-cp39-win32.whl", hash = "sha256:d314ed732c25d29775e84a960c3c60808b682c08d86602ec2c3008e1202e3bb6"},
+ {file = "coverage-5.5-cp39-cp39-win_amd64.whl", hash = "sha256:13034c4409db851670bc9acd836243aeee299949bd5673e11844befcb0149f03"},
+ {file = "coverage-5.5-pp36-none-any.whl", hash = "sha256:f030f8873312a16414c0d8e1a1ddff2d3235655a2174e3648b4fa66b3f2f1079"},
+ {file = "coverage-5.5-pp37-none-any.whl", hash = "sha256:2a3859cb82dcbda1cfd3e6f71c27081d18aa251d20a17d87d26d4cd216fb0af4"},
+ {file = "coverage-5.5.tar.gz", hash = "sha256:ebe78fe9a0e874362175b02371bdfbee64d8edc42a044253ddf4ee7d3c15212c"},
+]
+flake8 = [
+ {file = "flake8-3.9.2-py2.py3-none-any.whl", hash = "sha256:bf8fd333346d844f616e8d47905ef3a3384edae6b4e9beb0c5101e25e3110907"},
+ {file = "flake8-3.9.2.tar.gz", hash = "sha256:07528381786f2a6237b061f6e96610a4167b226cb926e2aa2b6b1d78057c576b"},
+]
+flake8-polyfill = [
+ {file = "flake8-polyfill-1.0.2.tar.gz", hash = "sha256:e44b087597f6da52ec6393a709e7108b2905317d0c0b744cdca6208e670d8eda"},
+ {file = "flake8_polyfill-1.0.2-py2.py3-none-any.whl", hash = "sha256:12be6a34ee3ab795b19ca73505e7b55826d5f6ad7230d31b18e106400169b9e9"},
+]
+halo = [
+ {file = "halo-0.0.31-py2-none-any.whl", hash = "sha256:5350488fb7d2aa7c31a1344120cee67a872901ce8858f60da7946cef96c208ab"},
+ {file = "halo-0.0.31.tar.gz", hash = "sha256:7b67a3521ee91d53b7152d4ee3452811e1d2a6321975137762eb3d70063cc9d6"},
+]
+hid = [
+ {file = "hid-1.0.4-py2-none-any.whl", hash = "sha256:fba9913f07030b01059b822b24c83b370ca3f444e9e6443bd662f9f1aa3f0780"},
+ {file = "hid-1.0.4.tar.gz", hash = "sha256:f61b0382f37a334bc8ba8604bc84b94875ee4f594fbbaf82b2c3b3e827883fc1"},
+]
+hjson = [
+ {file = "hjson-3.0.2-py3-none-any.whl", hash = "sha256:5546438bf4e1b52bc964c6a47c4ed10fa5fba8a1b264e22efa893e333baad2db"},
+ {file = "hjson-3.0.2.tar.gz", hash = "sha256:2838fd7200e5839ea4516ece953f3a19892c41089f0d933ba3f68e596aacfcd5"},
+]
+jsonschema = [
+ {file = "jsonschema-3.2.0-py2.py3-none-any.whl", hash = "sha256:4e5b3cf8216f577bee9ce139cbe72eca3ea4f292ec60928ff24758ce626cd163"},
+ {file = "jsonschema-3.2.0.tar.gz", hash = "sha256:c8a85b28d377cc7737e46e2d9f2b4f44ee3c0e1deac6bf46ddefc7187d30797a"},
+]
+log-symbols = [
+ {file = "log_symbols-0.0.14-py3-none-any.whl", hash = "sha256:4952106ff8b605ab7d5081dd2c7e6ca7374584eff7086f499c06edd1ce56dcca"},
+ {file = "log_symbols-0.0.14.tar.gz", hash = "sha256:cf0bbc6fe1a8e53f0d174a716bc625c4f87043cc21eb55dd8a740cfe22680556"},
+]
+mccabe = [
+ {file = "mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"},
+ {file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"},
+]
+milc = [
+ {file = "milc-1.6.2-py2.py3-none-any.whl", hash = "sha256:cb26404c7f3d6797c9c42005de732161e45e21294cde85845e914b279321bdad"},
+ {file = "milc-1.6.2.tar.gz", hash = "sha256:779710a0b9300bef3c5748158887e6c734659e147d55548d9e4701d7a7d5dddf"},
+]
+nose2 = [
+ {file = "nose2-0.10.0-py2.py3-none-any.whl", hash = "sha256:aa620e759f2c5018d9ba041340391913e282ecebd3c392027f1575847b093ec6"},
+ {file = "nose2-0.10.0.tar.gz", hash = "sha256:886ba617a96de0130c54b24479bd5c2d74d5c940d40f3809c3a275511a0c4a60"},
+]
+pep8-naming = [
+ {file = "pep8-naming-0.12.1.tar.gz", hash = "sha256:bb2455947757d162aa4cad55dba4ce029005cd1692f2899a21d51d8630ca7841"},
+ {file = "pep8_naming-0.12.1-py2.py3-none-any.whl", hash = "sha256:4a8daeaeb33cfcde779309fc0c9c0a68a3bbe2ad8a8308b763c5068f86eb9f37"},
+]
+pycodestyle = [
+ {file = "pycodestyle-2.7.0-py2.py3-none-any.whl", hash = "sha256:514f76d918fcc0b55c6680472f0a37970994e07bbb80725808c17089be302068"},
+ {file = "pycodestyle-2.7.0.tar.gz", hash = "sha256:c389c1d06bf7904078ca03399a4816f974a1d590090fecea0c63ec26ebaf1cef"},
+]
+pyflakes = [
+ {file = "pyflakes-2.3.1-py2.py3-none-any.whl", hash = "sha256:7893783d01b8a89811dd72d7dfd4d84ff098e5eed95cfa8905b22bbffe52efc3"},
+ {file = "pyflakes-2.3.1.tar.gz", hash = "sha256:f5bc8ecabc05bb9d291eb5203d6810b49040f6ff446a756326104746cc00c1db"},
+]
+pygments = [
+ {file = "Pygments-2.10.0-py3-none-any.whl", hash = "sha256:b8e67fe6af78f492b3c4b3e2970c0624cbf08beb1e493b2c99b9fa1b67a20380"},
+ {file = "Pygments-2.10.0.tar.gz", hash = "sha256:f398865f7eb6874156579fdf36bc840a03cab64d1cde9e93d68f46a425ec52c6"},
+]
+pyrsistent = [
+ {file = "pyrsistent-0.18.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:f4c8cabb46ff8e5d61f56a037974228e978f26bfefce4f61a4b1ac0ba7a2ab72"},
+ {file = "pyrsistent-0.18.0-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:da6e5e818d18459fa46fac0a4a4e543507fe1110e808101277c5a2b5bab0cd2d"},
+ {file = "pyrsistent-0.18.0-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:5e4395bbf841693eaebaa5bb5c8f5cdbb1d139e07c975c682ec4e4f8126e03d2"},
+ {file = "pyrsistent-0.18.0-cp36-cp36m-win32.whl", hash = "sha256:527be2bfa8dc80f6f8ddd65242ba476a6c4fb4e3aedbf281dfbac1b1ed4165b1"},
+ {file = "pyrsistent-0.18.0-cp36-cp36m-win_amd64.whl", hash = "sha256:2aaf19dc8ce517a8653746d98e962ef480ff34b6bc563fc067be6401ffb457c7"},
+ {file = "pyrsistent-0.18.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:58a70d93fb79dc585b21f9d72487b929a6fe58da0754fa4cb9f279bb92369396"},
+ {file = "pyrsistent-0.18.0-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:4916c10896721e472ee12c95cdc2891ce5890898d2f9907b1b4ae0f53588b710"},
+ {file = "pyrsistent-0.18.0-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:73ff61b1411e3fb0ba144b8f08d6749749775fe89688093e1efef9839d2dcc35"},
+ {file = "pyrsistent-0.18.0-cp37-cp37m-win32.whl", hash = "sha256:b29b869cf58412ca5738d23691e96d8aff535e17390128a1a52717c9a109da4f"},
+ {file = "pyrsistent-0.18.0-cp37-cp37m-win_amd64.whl", hash = "sha256:097b96f129dd36a8c9e33594e7ebb151b1515eb52cceb08474c10a5479e799f2"},
+ {file = "pyrsistent-0.18.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:772e94c2c6864f2cd2ffbe58bb3bdefbe2a32afa0acb1a77e472aac831f83427"},
+ {file = "pyrsistent-0.18.0-cp38-cp38-manylinux1_i686.whl", hash = "sha256:c1a9ff320fa699337e05edcaae79ef8c2880b52720bc031b219e5b5008ebbdef"},
+ {file = "pyrsistent-0.18.0-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:cd3caef37a415fd0dae6148a1b6957a8c5f275a62cca02e18474608cb263640c"},
+ {file = "pyrsistent-0.18.0-cp38-cp38-win32.whl", hash = "sha256:e79d94ca58fcafef6395f6352383fa1a76922268fa02caa2272fff501c2fdc78"},
+ {file = "pyrsistent-0.18.0-cp38-cp38-win_amd64.whl", hash = "sha256:a0c772d791c38bbc77be659af29bb14c38ced151433592e326361610250c605b"},
+ {file = "pyrsistent-0.18.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d5ec194c9c573aafaceebf05fc400656722793dac57f254cd4741f3c27ae57b4"},
+ {file = "pyrsistent-0.18.0-cp39-cp39-manylinux1_i686.whl", hash = "sha256:6b5eed00e597b5b5773b4ca30bd48a5774ef1e96f2a45d105db5b4ebb4bca680"},
+ {file = "pyrsistent-0.18.0-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:48578680353f41dca1ca3dc48629fb77dfc745128b56fc01096b2530c13fd426"},
+ {file = "pyrsistent-0.18.0-cp39-cp39-win32.whl", hash = "sha256:f3ef98d7b76da5eb19c37fda834d50262ff9167c65658d1d8f974d2e4d90676b"},
+ {file = "pyrsistent-0.18.0-cp39-cp39-win_amd64.whl", hash = "sha256:404e1f1d254d314d55adb8d87f4f465c8693d6f902f67eb6ef5b4526dc58e6ea"},
+ {file = "pyrsistent-0.18.0.tar.gz", hash = "sha256:773c781216f8c2900b42a7b638d5b517bb134ae1acbebe4d1e8f1f41ea60eb4b"},
+]
+pyusb = [
+ {file = "pyusb-1.2.1-py3-none-any.whl", hash = "sha256:2b4c7cb86dbadf044dfb9d3a4ff69fd217013dbe78a792177a3feb172449ea36"},
+ {file = "pyusb-1.2.1.tar.gz", hash = "sha256:a4cc7404a203144754164b8b40994e2849fde1cfff06b08492f12fff9d9de7b9"},
+]
+qmk = [
+ {file = "qmk-1.0.0-py2.py3-none-any.whl", hash = "sha256:63d69b97a533d91b0cfa7887e68cac7df52c6f7bddf4bf44d17ef1241d85ffff"},
+ {file = "qmk-1.0.0.tar.gz", hash = "sha256:da62eec73c4548cc37b0b9be3937202dc3a301dc2f2663610ecca751a610f9ca"},
+]
+qmk-dotty-dict = [
+ {file = "qmk_dotty_dict-1.3.0.post1-py3-none-any.whl", hash = "sha256:a9cb7fc3ff9631190fee0ecac14986a0ac7b4b6892347dc9d7486a4c4ea24492"},
+ {file = "qmk_dotty_dict-1.3.0.post1.tar.gz", hash = "sha256:3b611e393660bfaa6835c68e94784bae80fe07b8490978b5ecab03a0d2fc7ea2"},
+]
+six = [
+ {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"},
+ {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"},
+]
+spinners = [
+ {file = "spinners-0.0.24-py3-none-any.whl", hash = "sha256:2fa30d0b72c9650ad12bbe031c9943b8d441e41b4f5602b0ec977a19f3290e98"},
+ {file = "spinners-0.0.24.tar.gz", hash = "sha256:1eb6aeb4781d72ab42ed8a01dcf20f3002bf50740d7154d12fb8c9769bf9e27f"},
+]
+termcolor = [
+ {file = "termcolor-1.1.0.tar.gz", hash = "sha256:1d6d69ce66211143803fbc56652b41d73b4a400a2891d7bf7a1cdf4c02de613b"},
+]
+yapf = [
+ {file = "yapf-0.31.0-py2.py3-none-any.whl", hash = "sha256:e3a234ba8455fe201eaa649cdac872d590089a18b661e39bbac7020978dd9c2e"},
+ {file = "yapf-0.31.0.tar.gz", hash = "sha256:408fb9a2b254c302f49db83c59f9aa0b4b0fd0ec25be3a5c51181327922ff63d"},
+]
diff --git a/util/nix/pyproject.toml b/util/nix/pyproject.toml
new file mode 100644
index 0000000000..1ec8aacd4a
--- /dev/null
+++ b/util/nix/pyproject.toml
@@ -0,0 +1,36 @@
+# This file should be kept in sync with requirements.txt and requirements-dev.txt
+# It is particularly required by the Nix environment (see shell.nix). To update versions,
+# normally one would run "poetry update --lock"
+[tool.poetry]
+name = "qmk_firmware"
+version = "0.1.0"
+description = ""
+authors = []
+
+[tool.poetry.dependencies]
+python = "^3.8"
+appdirs = "*"
+argcomplete = "*"
+colorama = "*"
+hid = "*"
+hjson = "*"
+jsonschema = ">=3"
+milc = ">=1.4.2"
+Pygments = "*"
+pyusb = "*"
+qmk-dotty-dict = "*"
+
+# This dependency is not mentioned in requirements.txt (QMK CLI is not a
+# library package that is required by the Python code in qmk_firmware), but is
+# required to build a proper nix-shell environment.
+qmk = "*"
+
+[tool.poetry.dev-dependencies]
+nose2 = "*"
+flake8 = "*"
+pep8-naming = "*"
+yapf = "*"
+
+[build-system]
+requires = ["poetry-core>=1.0.0"]
+build-backend = "poetry.core.masonry.api"
diff --git a/util/nix/sources.json b/util/nix/sources.json
new file mode 100644
index 0000000000..caf5cb7d29
--- /dev/null
+++ b/util/nix/sources.json
@@ -0,0 +1,38 @@
+{
+ "niv": {
+ "branch": "master",
+ "description": "Easy dependency management for Nix projects",
+ "homepage": "https://github.com/nmattia/niv",
+ "owner": "nmattia",
+ "repo": "niv",
+ "rev": "af958e8057f345ee1aca714c1247ef3ba1c15f5e",
+ "sha256": "1qjavxabbrsh73yck5dcq8jggvh3r2jkbr6b5nlz5d9yrqm9255n",
+ "type": "tarball",
+ "url": "https://github.com/nmattia/niv/archive/af958e8057f345ee1aca714c1247ef3ba1c15f5e.tar.gz",
+ "url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
+ },
+ "nixpkgs": {
+ "branch": "nixpkgs-unstable",
+ "description": "Nix Packages collection",
+ "homepage": "",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "c0e881852006b132236cbf0301bd1939bb50867e",
+ "sha256": "0fy7z7yxk5n7yslsvx5cyc6h21qwi4bhxf3awhirniszlbvaazy2",
+ "type": "tarball",
+ "url": "https://github.com/NixOS/nixpkgs/archive/c0e881852006b132236cbf0301bd1939bb50867e.tar.gz",
+ "url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
+ },
+ "poetry2nix": {
+ "branch": "master",
+ "description": "Convert poetry projects to nix automagically [maintainer=@adisbladis] ",
+ "homepage": "",
+ "owner": "nix-community",
+ "repo": "poetry2nix",
+ "rev": "2d27d44397242b28c3f0081e0432e4f6c951f3a1",
+ "sha256": "06syfg150r59m4kksj5547b5kwxjxjaif5hiljcq966kb9hxsvmv",
+ "type": "tarball",
+ "url": "https://github.com/nix-community/poetry2nix/archive/2d27d44397242b28c3f0081e0432e4f6c951f3a1.tar.gz",
+ "url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
+ }
+}
diff --git a/util/nix/sources.nix b/util/nix/sources.nix
new file mode 100644
index 0000000000..1938409ddd
--- /dev/null
+++ b/util/nix/sources.nix
@@ -0,0 +1,174 @@
+# This file has been generated by Niv.
+
+let
+
+ #
+ # The fetchers. fetch_<type> fetches specs of type <type>.
+ #
+
+ fetch_file = pkgs: name: spec:
+ let
+ name' = sanitizeName name + "-src";
+ in
+ if spec.builtin or true then
+ builtins_fetchurl { inherit (spec) url sha256; name = name'; }
+ else
+ pkgs.fetchurl { inherit (spec) url sha256; name = name'; };
+
+ fetch_tarball = pkgs: name: spec:
+ let
+ name' = sanitizeName name + "-src";
+ in
+ if spec.builtin or true then
+ builtins_fetchTarball { name = name'; inherit (spec) url sha256; }
+ else
+ pkgs.fetchzip { name = name'; inherit (spec) url sha256; };
+
+ fetch_git = name: spec:
+ let
+ ref =
+ if spec ? ref then spec.ref else
+ if spec ? branch then "refs/heads/${spec.branch}" else
+ if spec ? tag then "refs/tags/${spec.tag}" else
+ abort "In git source '${name}': Please specify `ref`, `tag` or `branch`!";
+ in
+ builtins.fetchGit { url = spec.repo; inherit (spec) rev; inherit ref; };
+
+ fetch_local = spec: spec.path;
+
+ fetch_builtin-tarball = name: throw
+ ''[${name}] The niv type "builtin-tarball" is deprecated. You should instead use `builtin = true`.
+ $ niv modify ${name} -a type=tarball -a builtin=true'';
+
+ fetch_builtin-url = name: throw
+ ''[${name}] The niv type "builtin-url" will soon be deprecated. You should instead use `builtin = true`.
+ $ niv modify ${name} -a type=file -a builtin=true'';
+
+ #
+ # Various helpers
+ #
+
+ # https://github.com/NixOS/nixpkgs/pull/83241/files#diff-c6f540a4f3bfa4b0e8b6bafd4cd54e8bR695
+ sanitizeName = name:
+ (
+ concatMapStrings (s: if builtins.isList s then "-" else s)
+ (
+ builtins.split "[^[:alnum:]+._?=-]+"
+ ((x: builtins.elemAt (builtins.match "\\.*(.*)" x) 0) name)
+ )
+ );
+
+ # The set of packages used when specs are fetched using non-builtins.
+ mkPkgs = sources: system:
+ let
+ sourcesNixpkgs =
+ import (builtins_fetchTarball { inherit (sources.nixpkgs) url sha256; }) { inherit system; };
+ hasNixpkgsPath = builtins.any (x: x.prefix == "nixpkgs") builtins.nixPath;
+ hasThisAsNixpkgsPath = <nixpkgs> == ./.;
+ in
+ if builtins.hasAttr "nixpkgs" sources
+ then sourcesNixpkgs
+ else if hasNixpkgsPath && ! hasThisAsNixpkgsPath then
+ import <nixpkgs> {}
+ else
+ abort
+ ''
+ Please specify either <nixpkgs> (through -I or NIX_PATH=nixpkgs=...) or
+ add a package called "nixpkgs" to your sources.json.
+ '';
+
+ # The actual fetching function.
+ fetch = pkgs: name: spec:
+
+ if ! builtins.hasAttr "type" spec then
+ abort "ERROR: niv spec ${name} does not have a 'type' attribute"
+ else if spec.type == "file" then fetch_file pkgs name spec
+ else if spec.type == "tarball" then fetch_tarball pkgs name spec
+ else if spec.type == "git" then fetch_git name spec
+ else if spec.type == "local" then fetch_local spec
+ else if spec.type == "builtin-tarball" then fetch_builtin-tarball name
+ else if spec.type == "builtin-url" then fetch_builtin-url name
+ else
+ abort "ERROR: niv spec ${name} has unknown type ${builtins.toJSON spec.type}";
+
+ # If the environment variable NIV_OVERRIDE_${name} is set, then use
+ # the path directly as opposed to the fetched source.
+ replace = name: drv:
+ let
+ saneName = stringAsChars (c: if isNull (builtins.match "[a-zA-Z0-9]" c) then "_" else c) name;
+ ersatz = builtins.getEnv "NIV_OVERRIDE_${saneName}";
+ in
+ if ersatz == "" then drv else
+ # this turns the string into an actual Nix path (for both absolute and
+ # relative paths)
+ if builtins.substring 0 1 ersatz == "/" then /. + ersatz else /. + builtins.getEnv "PWD" + "/${ersatz}";
+
+ # Ports of functions for older nix versions
+
+ # a Nix version of mapAttrs if the built-in doesn't exist
+ mapAttrs = builtins.mapAttrs or (
+ f: set: with builtins;
+ listToAttrs (map (attr: { name = attr; value = f attr set.${attr}; }) (attrNames set))
+ );
+
+ # https://github.com/NixOS/nixpkgs/blob/0258808f5744ca980b9a1f24fe0b1e6f0fecee9c/lib/lists.nix#L295
+ range = first: last: if first > last then [] else builtins.genList (n: first + n) (last - first + 1);
+
+ # https://github.com/NixOS/nixpkgs/blob/0258808f5744ca980b9a1f24fe0b1e6f0fecee9c/lib/strings.nix#L257
+ stringToCharacters = s: map (p: builtins.substring p 1 s) (range 0 (builtins.stringLength s - 1));
+
+ # https://github.com/NixOS/nixpkgs/blob/0258808f5744ca980b9a1f24fe0b1e6f0fecee9c/lib/strings.nix#L269
+ stringAsChars = f: s: concatStrings (map f (stringToCharacters s));
+ concatMapStrings = f: list: concatStrings (map f list);
+ concatStrings = builtins.concatStringsSep "";
+
+ # https://github.com/NixOS/nixpkgs/blob/8a9f58a375c401b96da862d969f66429def1d118/lib/attrsets.nix#L331
+ optionalAttrs = cond: as: if cond then as else {};
+
+ # fetchTarball version that is compatible between all the versions of Nix
+ builtins_fetchTarball = { url, name ? null, sha256 }@attrs:
+ let
+ inherit (builtins) lessThan nixVersion fetchTarball;
+ in
+ if lessThan nixVersion "1.12" then
+ fetchTarball ({ inherit url; } // (optionalAttrs (!isNull name) { inherit name; }))
+ else
+ fetchTarball attrs;
+
+ # fetchurl version that is compatible between all the versions of Nix
+ builtins_fetchurl = { url, name ? null, sha256 }@attrs:
+ let
+ inherit (builtins) lessThan nixVersion fetchurl;
+ in
+ if lessThan nixVersion "1.12" then
+ fetchurl ({ inherit url; } // (optionalAttrs (!isNull name) { inherit name; }))
+ else
+ fetchurl attrs;
+
+ # Create the final "sources" from the config
+ mkSources = config:
+ mapAttrs (
+ name: spec:
+ if builtins.hasAttr "outPath" spec
+ then abort
+ "The values in sources.json should not have an 'outPath' attribute"
+ else
+ spec // { outPath = replace name (fetch config.pkgs name spec); }
+ ) config.sources;
+
+ # The "config" used by the fetchers
+ mkConfig =
+ { sourcesFile ? if builtins.pathExists ./sources.json then ./sources.json else null
+ , sources ? if isNull sourcesFile then {} else builtins.fromJSON (builtins.readFile sourcesFile)
+ , system ? builtins.currentSystem
+ , pkgs ? mkPkgs sources system
+ }: rec {
+ # The sources, i.e. the attribute set of spec name to spec
+ inherit sources;
+
+ # The "pkgs" (evaluated nixpkgs) to use for e.g. non-builtin fetchers
+ inherit pkgs;
+ };
+
+in
+mkSources (mkConfig {}) // { __functor = _: settings: mkSources (mkConfig settings); }
diff --git a/util/qmk_install.sh b/util/qmk_install.sh
index 943069453a..5f22ba0ad5 100755
--- a/util/qmk_install.sh
+++ b/util/qmk_install.sh
@@ -1,6 +1,6 @@
-#!/bin/bash
+#!/usr/bin/env bash
-QMK_FIRMWARE_DIR=$(cd -P -- "$(dirname -- "$0")/.." && pwd -P)
+QMK_FIRMWARE_DIR=$(cd -P -- "$(dirname -- "$0")/.." >/dev/null && pwd -P)
QMK_FIRMWARE_UTIL_DIR=$QMK_FIRMWARE_DIR/util
if [ "$1" = "-y" ]; then
SKIP_PROMPT='-y'
diff --git a/util/reset.eep b/util/reset.eep
new file mode 100644
index 0000000000..a8a75389fe
--- /dev/null
+++ b/util/reset.eep
@@ -0,0 +1,9 @@
+:10000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+:10001000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
+:10002000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
+:10003000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0
+:10004000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
+:10005000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
+:10006000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
+:10007000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90
+:00000001FF
diff --git a/util/rules_cleaner.sh b/util/rules_cleaner.sh
index ac27c2b09b..0367ae849f 100755
--- a/util/rules_cleaner.sh
+++ b/util/rules_cleaner.sh
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
# This script finds all rules.mk files in keyboards/ subdirectories,
# and deletes the build option filesize impacts from them.
diff --git a/util/stm32eeprom_parser.py b/util/stm32eeprom_parser.py
new file mode 100755
index 0000000000..e08b67064b
--- /dev/null
+++ b/util/stm32eeprom_parser.py
@@ -0,0 +1,316 @@
+#!/usr/bin/env python
+#
+# Copyright 2021 Don Kjer
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+from __future__ import print_function
+
+import argparse
+from struct import pack, unpack
+import os, sys
+
+MAGIC_FEEA = '\xea\xff\xfe\xff'
+
+MAGIC_FEE9 = '\x16\x01'
+EMPTY_WORD = '\xff\xff'
+WORD_ENCODING = 0x8000
+VALUE_NEXT = 0x6000
+VALUE_RESERVED = 0x4000
+VALUE_ENCODED = 0x2000
+BYTE_RANGE = 0x80
+
+CHUNK_SIZE = 1024
+
+STRUCT_FMTS = {
+ 1: 'B',
+ 2: 'H',
+ 4: 'I'
+}
+PRINTABLE='0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~ '
+
+EECONFIG_V1 = [
+ ("MAGIC", 0, 2),
+ ("DEBUG", 2, 1),
+ ("DEFAULT_LAYER", 3, 1),
+ ("KEYMAP", 4, 1),
+ ("MOUSEKEY_ACCEL", 5, 1),
+ ("BACKLIGHT", 6, 1),
+ ("AUDIO", 7, 1),
+ ("RGBLIGHT", 8, 4),
+ ("UNICODEMODE", 12, 1),
+ ("STENOMODE", 13, 1),
+ ("HANDEDNESS", 14, 1),
+ ("KEYBOARD", 15, 4),
+ ("USER", 19, 4),
+ ("VELOCIKEY", 23, 1),
+ ("HAPTIC", 24, 4),
+ ("MATRIX", 28, 4),
+ ("MATRIX_EXTENDED", 32, 2),
+ ("KEYMAP_UPPER_BYTE", 34, 1),
+]
+VIABASE_V1 = 35
+
+VERBOSE = False
+
+def parseArgs():
+ parser = argparse.ArgumentParser(description='Decode an STM32 emulated eeprom dump')
+ parser.add_argument('-s', '--size', type=int,
+ help='Size of the emulated eeprom (default: input_size / 2)')
+ parser.add_argument('-o', '--output', help='File to write decoded eeprom to')
+ parser.add_argument('-y', '--layout-options-size', type=int,
+ help='VIA layout options size (default: 1)', default=1)
+ parser.add_argument('-t', '--custom-config-size', type=int,
+ help='VIA custom config size (default: 0)', default=0)
+ parser.add_argument('-l', '--layers', type=int,
+ help='VIA keyboard layers (default: 4)', default=4)
+ parser.add_argument('-r', '--rows', type=int, help='VIA matrix rows')
+ parser.add_argument('-c', '--cols', type=int, help='VIA matrix columns')
+ parser.add_argument('-m', '--macros', type=int,
+ help='VIA macro count (default: 16)', default=16)
+ parser.add_argument('-C', '--canonical', action='store_true',
+ help='Canonical hex+ASCII display.')
+ parser.add_argument('-v', '--verbose', action='store_true', help='Verbose output')
+ parser.add_argument('input', help='Raw contents of the STM32 flash area used to emulate eeprom')
+ return parser.parse_args()
+
+
+def decodeEepromFEEA(in_file, size):
+ decoded=size*[None]
+ pos = 0
+ while True:
+ chunk = in_file.read(CHUNK_SIZE)
+ for i in range(0, len(chunk), 2):
+ decoded[pos] = unpack('B', chunk[i])[0]
+ pos += 1
+ if pos >= size:
+ break
+
+ if len(chunk) < CHUNK_SIZE or pos >= size:
+ break
+ return decoded
+
+def decodeEepromFEE9(in_file, size):
+ decoded=size*[None]
+ pos = 0
+ # Read compacted flash
+ while True:
+ read_size = min(size - pos, CHUNK_SIZE)
+ chunk = in_file.read(read_size)
+ for i in range(len(chunk)):
+ decoded[pos] = unpack('B', chunk[i])[0] ^ 0xFF
+ pos += 1
+ if pos >= size:
+ break
+
+ if len(chunk) < read_size or pos >= size:
+ break
+ if VERBOSE:
+ print("COMPACTED EEPROM:")
+ dumpBinary(decoded, True)
+ print("WRITE LOG:")
+ # Read write log
+ while True:
+ entry = in_file.read(2)
+ if len(entry) < 2:
+ print("Partial log address at position 0x%04x" % pos, file=sys.stderr)
+ break
+ pos += 2
+
+ if entry == EMPTY_WORD:
+ break
+
+ be_entry = unpack('>H', entry)[0]
+ entry = unpack('H', entry)[0]
+ if not (entry & WORD_ENCODING):
+ address = entry >> 8
+ decoded[address] = entry & 0xFF
+ if VERBOSE:
+ print("[0x%04x]: BYTE 0x%02x = 0x%02x" % (be_entry, address, decoded[address]))
+ else:
+ if (entry & VALUE_NEXT) == VALUE_NEXT:
+ # Read next word as value
+ value = in_file.read(2)
+ if len(value) < 2:
+ print("Partial log value at position 0x%04x" % pos, file=sys.stderr)
+ break
+ pos += 2
+ address = entry & 0x1FFF
+ address <<= 1
+ address += BYTE_RANGE
+ decoded[address] = unpack('B', value[0])[0] ^ 0xFF
+ decoded[address+1] = unpack('B', value[1])[0] ^ 0xFF
+ be_value = unpack('>H', value)[0]
+ if VERBOSE:
+ print("[0x%04x 0x%04x]: WORD 0x%04x = 0x%02x%02x" % (be_entry, be_value, address, decoded[address+1], decoded[address]))
+ else:
+ # Reserved for future use
+ if entry & VALUE_RESERVED:
+ if VERBOSE:
+ print("[0x%04x]: RESERVED 0x%04x" % (be_entry, address))
+ continue
+ address = entry & 0x1FFF
+ address <<= 1
+ decoded[address] = (entry & VALUE_ENCODED) >> 13
+ decoded[address+1] = 0
+ if VERBOSE:
+ print("[0x%04x]: ENCODED 0x%04x = 0x%02x%02x" % (be_entry, address, decoded[address+1], decoded[address]))
+
+ return decoded
+
+def dumpBinary(data, canonical):
+ def display(pos, row):
+ print("%04x" % pos, end='')
+ for i in range(len(row)):
+ if i % 8 == 0:
+ print(" ", end='')
+ char = row[i]
+ if char is None:
+ print(" ", end='')
+ else:
+ print(" %02x" % row[i], end='')
+ if canonical:
+ print(" |", end='')
+ for i in range(len(row)):
+ char = row[i]
+ if char is None:
+ char = " "
+ else:
+ char = chr(char)
+ if char not in PRINTABLE:
+ char = "."
+ print(char, end='')
+ print("|", end='')
+
+ print("")
+
+ size = len(data)
+ prev_row = ''
+ first_repeat = True
+ for pos in range(0, size, 16):
+ row=data[pos:pos+16]
+ row[len(row):16] = (16-len(row))*[None]
+ if row == prev_row:
+ if first_repeat:
+ print("*")
+ first_repeat = False
+ else:
+ first_repeat = True
+ display(pos, row)
+ prev_row = row
+ print("%04x" % (pos+16))
+
+def dumpEeconfig(data, eeconfig):
+ print("EECONFIG:")
+ for (name, pos, length) in eeconfig:
+ fmt = STRUCT_FMTS[length]
+ value = unpack(fmt, ''.join([chr(x) for x in data[pos:pos+length]]))[0]
+ print(("%%04x %%s = 0x%%0%dx" % (length * 2)) % (pos, name, value))
+
+def dumpVia(data, base, layers, cols, rows, macros,
+ layout_options_size, custom_config_size):
+ magicYear = data[base + 0]
+ magicMonth = data[base + 1]
+ magicDay = data[base + 2]
+ # Sanity check
+ if not 10 <= magicYear <= 0x99 or \
+ not 0 <= magicMonth <= 0x12 or \
+ not 0 <= magicDay <= 0x31:
+ print("ERROR: VIA Signature is not valid; Year:%x, Month:%x, Day:%x" % (magicYear, magicMonth, magicDay))
+ return
+ if cols is None or rows is None:
+ print("ERROR: VIA dump requires specifying --rows and --cols", file=sys.stderr)
+ return 2
+ print("VIA:")
+ # Decode magic
+ print("%04x MAGIC = 20%02x-%02x-%02x" % (base, magicYear, magicMonth, magicDay))
+ # Decode layout options
+ options = 0
+ pos = base + 3
+ for i in range(base+3, base+3+layout_options_size):
+ options = options << 8
+ options |= data[i]
+ print(("%%04x LAYOUT_OPTIONS = 0x%%0%dx" % (layout_options_size * 2)) % (pos, options))
+ pos += layout_options_size + custom_config_size
+ # Decode keycodes
+ keymap_size = layers * rows * cols * 2
+ if (pos + keymap_size) >= (len(data) - 1):
+ print("ERROR: VIA keymap requires %d bytes, but only %d available" % (keymap_size, len(data) - pos))
+ return 3
+ for layer in range(layers):
+ print("%s LAYER %d %s" % ('-'*int(cols*2.5), layer, '-'*int(cols*2.5)))
+ for row in range(rows):
+ print("%04x | " % pos, end='')
+ for col in range(cols):
+ keycode = (data[pos] << 8) | (data[pos+1])
+ print(" %04x" % keycode, end='')
+ pos += 2
+ print("")
+ # Decode macros
+ for macro_num in range(macros):
+ macro = ""
+ macro_pos = pos
+ while pos < len(data):
+ char = chr(data[pos])
+ pos += 1
+ if char == '\x00':
+ print("%04x MACRO[%d] = '%s'" % (macro_pos, macro_num, macro))
+ break
+ else:
+ macro += char
+ return 0
+
+
+def decodeSTM32Eeprom(input, canonical, size=None, output=None, **kwargs):
+ input_size = os.path.getsize(input)
+ if size is None:
+ size = input_size >> 1
+
+ # Read the first few bytes to check magic signature
+ with open(input, 'rb') as in_file:
+ magic=in_file.read(4)
+ in_file.seek(0)
+
+ if magic == MAGIC_FEEA:
+ decoded = decodeEepromFEEA(in_file, size)
+ eeconfig = EECONFIG_V1
+ via_base = VIABASE_V1
+ elif magic[:2] == MAGIC_FEE9:
+ decoded = decodeEepromFEE9(in_file, size)
+ eeconfig = EECONFIG_V1
+ via_base = VIABASE_V1
+ else:
+ print("Unknown magic signature: %s" % " ".join(["0x%02x" % ord(x) for x in magic]), file=sys.stderr)
+ return 1
+
+ if output is not None:
+ with open(output, 'wb') as out_file:
+ out_file.write(pack('%dB' % len(decoded), *decoded))
+ print("DECODED EEPROM:")
+ dumpBinary(decoded, canonical)
+ dumpEeconfig(decoded, eeconfig)
+ if kwargs['rows'] is not None and kwargs['cols'] is not None:
+ return dumpVia(decoded, via_base, **kwargs)
+
+ return 0
+
+def main():
+ global VERBOSE
+ kwargs = vars(parseArgs())
+ VERBOSE = kwargs.pop('verbose')
+ return decodeSTM32Eeprom(**kwargs)
+
+if __name__ == '__main__':
+ sys.exit(main())
diff --git a/util/travis_utils.sh b/util/travis_utils.sh
deleted file mode 100755
index e949946e22..0000000000
--- a/util/travis_utils.sh
+++ /dev/null
@@ -1,25 +0,0 @@
-# Use this by sourcing it in your script.
-
-# Provide sane defaults for travis environment
-TRAVIS_BRANCH="${TRAVIS_BRANCH:master}"
-TRAVIS_PULL_REQUEST="${TRAVIS_PULL_REQUEST:false}"
-TRAVIS_COMMIT_MESSAGE="${TRAVIS_COMMIT_MESSAGE:-none}"
-TRAVIS_COMMIT_RANGE="${TRAVIS_COMMIT_RANGE:-HEAD~1..HEAD}"
-
-# test force push
-#TRAVIS_COMMIT_RANGE="c287f1bfc5c8...81f62atc4c1d"
-
-# Extra variables
-LOCAL_BRANCH=$(git rev-parse --abbrev-ref HEAD)
-QMK_CHANGES=$(git diff --name-only -n 1 ${TRAVIS_COMMIT_RANGE})
-NUM_CORE_CHANGES=$(echo "$QMK_CHANGES" | grep -Ec -e '^Makefile' -e '^[^/]*.mk' -e '^drivers/' -e '^lib/atsam' -e '^lib/lib8tion/' -e '^platforms' -e '^quantum' -e '^tests' -e '^tmk_core')
-
-# if docker is installed - patch calls to within the qmk docker image
-if command -v docker >/dev/null; then
- function make() {
- docker run --rm -e MAKEFLAGS="$MAKEFLAGS" -w /qmk_firmware/ -v "$PWD":/qmk_firmware --user $(id -u):$(id -g) qmkfm/base_container make "$@"
- }
- function qmk() {
- docker run --rm -w /qmk_firmware/ -v "$PWD":/qmk_firmware --user $(id -u):$(id -g) qmkfm/base_container bin/qmk "$@"
- }
-fi
diff --git a/util/udev/50-qmk.rules b/util/udev/50-qmk.rules
index 679fe4ced3..db27d4dc81 100644
--- a/util/udev/50-qmk.rules
+++ b/util/udev/50-qmk.rules
@@ -63,3 +63,9 @@ SUBSYSTEMS=="usb", ATTRS{idVendor}=="2a03", ATTRS{idProduct}=="0037", TAG+="uacc
# hid_listen
KERNEL=="hidraw*", MODE="0660", GROUP="plugdev", TAG+="uaccess", TAG+="udev-acl"
+
+# hid bootloaders
+## QMK HID
+SUBSYSTEMS=="usb", ATTRS{idVendor}=="03eb", ATTRS{idProduct}=="2067", TAG+="uaccess"
+## PJRC's HalfKay
+SUBSYSTEMS=="usb", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="0478", TAG+="uaccess"
diff --git a/util/uf2conv.py b/util/uf2conv.py
index 044a7f2318..8677a828c9 100755
--- a/util/uf2conv.py
+++ b/util/uf2conv.py
@@ -78,7 +78,7 @@ def convert_from_uf2(buf):
if datalen > 476:
assert False, "Invalid UF2 data size at " + ptr
newaddr = hd[3]
- if curraddr == None:
+ if curraddr is None:
appstartaddr = newaddr
curraddr = newaddr
padding = newaddr - curraddr
@@ -171,7 +171,7 @@ def convert_from_hex_to_uf2(buf):
break
elif tp == 0:
addr = upper | (rec[1] << 8) | rec[2]
- if appstartaddr == None:
+ if appstartaddr is None:
appstartaddr = addr
i = 4
while i < len(rec) - 1:
@@ -215,7 +215,7 @@ def get_drives():
def has_info(d):
try:
return os.path.isfile(d + INFO_FILE)
- except:
+ except Exception:
return False
return list(filter(has_info, drives))
@@ -300,7 +300,7 @@ def main():
(ext, len(outbuf), appstartaddr))
if args.convert or ext != "uf2":
drives = []
- if args.output == None:
+ if args.output is None:
args.output = "flash." + ext
else:
drives = get_drives()
diff --git a/util/update_chibios_mirror.sh b/util/update_chibios_mirror.sh
new file mode 100755
index 0000000000..83aee22817
--- /dev/null
+++ b/util/update_chibios_mirror.sh
@@ -0,0 +1,92 @@
+#!/bin/bash
+
+################################
+# Configuration
+
+# The ChibiOS branches to mirror
+chibios_branches="trunk stable_20.3.x stable_21.6.x"
+
+# The ChibiOS tags to mirror
+chibios_tags="ver20.3.1 ver20.3.2 ver20.3.3 ver21.6.0"
+
+# The ChibiOS-Contrib branches to mirror
+contrib_branches="chibios-20.3.x"
+
+################################
+# Actions
+
+set -eEuo pipefail
+umask 022
+
+this_script="$(realpath "${BASH_SOURCE[0]}")"
+script_dir="$(realpath "$(dirname "$this_script")")"
+qmk_firmware_dir="$(realpath "$script_dir/../")"
+chibios_dir="$qmk_firmware_dir/lib/chibios"
+contrib_dir="$qmk_firmware_dir/lib/chibios-contrib"
+
+chibios_git_location=$(realpath "$chibios_dir/$(cat "$chibios_dir/.git" | awk '/gitdir:/ {print $2}')")
+chibios_git_config=$(realpath "$chibios_git_location/config")
+contrib_git_location=$(realpath "$contrib_dir/$(cat "$contrib_dir/.git" | awk '/gitdir:/ {print $2}')")
+contrib_git_config=$(realpath "$contrib_git_location/config")
+
+cd "$chibios_dir"
+
+if [[ -z "$(cat "$chibios_git_config" | grep '\[svn-remote "svn"\]')" ]] ; then
+ git svn init --stdlayout --prefix='svn/' http://svn.osdn.net/svnroot/chibios/
+fi
+
+if [[ -z "$(cat "$chibios_git_config" | grep '\[remote "qmk"\]')" ]] ; then
+ git remote add qmk git@github.com:qmk/ChibiOS.git
+ git remote set-url qmk git@github.com:qmk/ChibiOS.git --push
+else
+ git remote set-url qmk git@github.com:qmk/ChibiOS.git
+ git remote set-url qmk git@github.com:qmk/ChibiOS.git --push
+fi
+
+echo "Updating remotes..."
+git fetch --all --tags --prune
+
+echo "Fetching latest from subversion..."
+git svn fetch
+
+echo "Updating ChibiOS branches..."
+for branch in $chibios_branches ; do
+ echo "Creating branch 'svn-mirror/$branch' from 'svn/$branch'..."
+ git branch -f svn-mirror/$branch svn/$branch \
+ && git push qmk svn-mirror/$branch
+done
+
+echo "Updating ChibiOS tags..."
+for tagname in $chibios_tags ; do
+ echo "Creating tag 'svn-mirror/$tagname' from 'svn/tags/$tagname'..."
+ GIT_COMMITTER_DATE="$(git log -n1 --pretty=format:'%ad' svn/tags/$tagname)" git tag -f -a -m "Tagging $tagname" svn-mirror/$tagname svn/tags/$tagname
+ git push qmk svn-mirror/$tagname
+done
+
+cd "$contrib_dir"
+
+if [[ -z "$(cat "$contrib_git_config" | grep '\[remote "qmk"\]')" ]] ; then
+ git remote add qmk git@github.com:qmk/ChibiOS-Contrib.git
+ git remote set-url qmk git@github.com:qmk/ChibiOS-Contrib.git --push
+else
+ git remote set-url qmk git@github.com:qmk/ChibiOS-Contrib.git
+ git remote set-url qmk git@github.com:qmk/ChibiOS-Contrib.git --push
+fi
+
+if [[ -z "$(cat "$contrib_git_config" | grep '\[remote "upstream"\]')" ]] ; then
+ git remote add upstream git@github.com:ChibiOS/ChibiOS-Contrib.git
+ git remote set-url upstream git@github.com:ChibiOS/ChibiOS-Contrib.git --push
+else
+ git remote set-url upstream git@github.com:ChibiOS/ChibiOS-Contrib.git
+ git remote set-url upstream git@github.com:ChibiOS/ChibiOS-Contrib.git --push
+fi
+
+echo "Updating remotes..."
+git fetch --all --tags --prune
+
+echo "Updating ChibiOS-Contrib branches..."
+for branch in $contrib_branches ; do
+ echo "Creating branch 'mirror/$branch' from 'upstream/$branch'..."
+ git branch -f mirror/$branch upstream/$branch \
+ && git push qmk mirror/$branch
+done
diff --git a/util/vagrant/Dockerfile b/util/vagrant/Dockerfile
index 1936ee023a..951d4fc40d 100644
--- a/util/vagrant/Dockerfile
+++ b/util/vagrant/Dockerfile
@@ -1,4 +1,4 @@
-FROM qmkfm/base_container
+FROM qmkfm/qmk_cli
# Basic upgrades; install sudo and SSH.
RUN apt-get update && apt-get install --no-install-recommends -y \
diff --git a/util/vagrant/readme.md b/util/vagrant/readme.md
index e4b870a642..a8396007ee 100644
--- a/util/vagrant/readme.md
+++ b/util/vagrant/readme.md
@@ -1,7 +1,7 @@
# QMK Vagrant Utilities
## Dockerfile
-Vagrant-friendly `qmkfm/base_container`.
+Vagrant-friendly `qmkfm/qmk_cli`.
In order for the Docker provider and `vagrant ssh` to function the container has a few extra requirements.