Refactor new-keyboard to be python3.7 compatible (#14707)

* Use copy_tree from distutils for python 3.7 support

* Bump python version in docs

* Changed new-keyboard to use printf-style format strings

* Use username for manunfacturer / maintainer

* Update lib/python/qmk/cli/new/keyboard.py

Co-authored-by: Zach White <skullydazed@drpepper.org>

Co-authored-by: Zach White <skullydazed@drpepper.org>
master
Mikkel Jeppesen 2021-11-04 22:14:43 +01:00 committed by GitHub
parent 6437045166
commit fefd7fdc51
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 91 additions and 188 deletions

View File

@ -1,19 +1,5 @@
/* // Copyright %(YEAR)s %(YOUR_NAME)s (@%(USER_NAME)s)
Copyright %YEAR% %YOUR_NAME% // SPDX-License-Identifier: GPL-2.0-or-later
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/>.
*/
#pragma once #pragma once
@ -23,8 +9,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define VENDOR_ID 0xFEED #define VENDOR_ID 0xFEED
#define PRODUCT_ID 0x0000 #define PRODUCT_ID 0x0000
#define DEVICE_VER 0x0001 #define DEVICE_VER 0x0001
#define MANUFACTURER %YOUR_NAME% #define MANUFACTURER %(USER_NAME)s
#define PRODUCT %KEYBOARD% #define PRODUCT %(KEYBOARD)s
/* key matrix size */ /* key matrix size */
#define MATRIX_ROWS 2 #define MATRIX_ROWS 2

View File

@ -1,20 +1,20 @@
# %KEYBOARD% # %(KEYBOARD)s
![%KEYBOARD%](imgur.com image replace me!) ![%(KEYBOARD)s](imgur.com image replace me!)
*A short description of the keyboard/project* *A short description of the keyboard/project*
* Keyboard Maintainer: [%YOUR_NAME%](https://github.com/yourusername) * Keyboard Maintainer: [%(YOUR_NAME)s](https://github.com/%(USER_NAME)s)
* Hardware Supported: *The PCBs, controllers supported* * Hardware Supported: *The PCBs, controllers supported*
* Hardware Availability: *Links to where you can find this hardware* * Hardware Availability: *Links to where you can find this hardware*
Make example for this keyboard (after setting up your build environment): Make example for this keyboard (after setting up your build environment):
make %KEYBOARD%:default make %(KEYBOARD)s:default
Flashing example for this keyboard: Flashing example for this keyboard:
make %KEYBOARD%:default:flash make %(KEYBOARD)s:default:flash
See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs). See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).

View File

@ -0,0 +1,4 @@
// Copyright %(YEAR)s %(YOUR_NAME)s (@%(USER_NAME)s)
// SPDX-License-Identifier: GPL-2.0-or-later
#include "%(KEYBOARD)s.h"

View File

@ -0,0 +1,22 @@
// Copyright %(YEAR)s %(YOUR_NAME)s (@%(USER_NAME)s)
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include "quantum.h"
/* This is a shortcut to help you visually see your layout.
*
* The first section contains all of the arguments representing the physical
* layout of the board and position of the keys.
*
* The second converts the arguments into a two-dimensional array which
* represents the switch matrix.
*/
#define LAYOUT( \
k00, k01, k02, \
k10, k12 \
) { \
{ k00, k01, k02 }, \
{ k10, KC_NO, k12 } \
}

View File

@ -1,7 +1,7 @@
{ {
"keyboard_name": "%KEYBOARD%", "keyboard_name": "%(KEYBOARD)s",
"url": "", "url": "",
"maintainer": "%YOUR_NAME%", "maintainer": "%(USER_NAME)s",
"layouts": { "layouts": {
"LAYOUT": { "LAYOUT": {
"layout": [ "layout": [

View File

@ -1,17 +0,0 @@
/* Copyright %YEAR% %YOUR_NAME%
*
* 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/>.
*/
#include "%KEYBOARD%.h"

View File

@ -1,35 +0,0 @@
/* Copyright %YEAR% %YOUR_NAME%
*
* 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/>.
*/
#pragma once
#include "quantum.h"
/* This is a shortcut to help you visually see your layout.
*
* The first section contains all of the arguments representing the physical
* layout of the board and position of the keys.
*
* The second converts the arguments into a two-dimensional array which
* represents the switch matrix.
*/
#define LAYOUT( \
k00, k01, k02, \
k10, k12 \
) { \
{ k00, k01, k02 }, \
{ k10, KC_NO, k12 } \
}

View File

@ -1,18 +1,6 @@
/* Copyright %YEAR% %YOUR_NAME% // Copyright %(YEAR)s %(YOUR_NAME)s (@%(USER_NAME)s)
* // SPDX-License-Identifier: GPL-2.0-or-later
* 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/>.
*/
#include QMK_KEYBOARD_H #include QMK_KEYBOARD_H
// Defines names for use in layer keycodes and the keymap // Defines names for use in layer keycodes and the keymap
@ -21,12 +9,6 @@ enum layer_names {
_FN _FN
}; };
// Defines the keycodes used by our macros in process_record_user
enum custom_keycodes {
QMKBEST = SAFE_RANGE,
QMKURL
};
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/* Base */ /* Base */
[_BASE] = LAYOUT( [_BASE] = LAYOUT(
@ -34,29 +16,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
KC_TAB, KC_SPC KC_TAB, KC_SPC
), ),
[_FN] = LAYOUT( [_FN] = LAYOUT(
QMKBEST, QMKURL, _______, _______, _______, _______,
RESET, XXXXXXX RESET, XXXXXXX
) )
}; };
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
switch (keycode) {
case QMKBEST:
if (record->event.pressed) {
// when keycode QMKBEST is pressed
SEND_STRING("QMK is the best thing ever!");
} else {
// when keycode QMKBEST is released
}
break;
case QMKURL:
if (record->event.pressed) {
// when keycode QMKURL is pressed
SEND_STRING("https://qmk.fm/\n");
} else {
// when keycode QMKURL is released
}
break;
}
return true;
}

View File

@ -1 +1 @@
# The default keymap for %KEYBOARD% # The default keymap for %(KEYBOARD)s

View File

@ -1,19 +1,5 @@
/* // Copyright %(YEAR)s %(YOUR_NAME)s (@%(USER_NAME)s)
Copyright %YEAR% %YOUR_NAME% // SPDX-License-Identifier: GPL-2.0-or-later
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/>.
*/
#pragma once #pragma once
@ -23,8 +9,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define VENDOR_ID 0xFEED #define VENDOR_ID 0xFEED
#define PRODUCT_ID 0x0000 #define PRODUCT_ID 0x0000
#define DEVICE_VER 0x0001 #define DEVICE_VER 0x0001
#define MANUFACTURER %YOUR_NAME% #define MANUFACTURER %(USER_NAME)s
#define PRODUCT %KEYBOARD% #define PRODUCT %(KEYBOARD)s
/* key matrix size */ /* key matrix size */
#define MATRIX_ROWS 8 #define MATRIX_ROWS 8

View File

@ -1,20 +1,20 @@
# %KEYBOARD% # %(KEYBOARD)s
![%KEYBOARD%](imgur.com image replace me!) ![%(KEYBOARD)s](imgur.com image replace me!)
*A short description of the keyboard/project* *A short description of the keyboard/project*
* Keyboard Maintainer: [%YOUR_NAME%](https://github.com/yourusername) * Keyboard Maintainer: [%(YOUR_NAME)s](https://github.com/yourusername)
* Hardware Supported: *The PCBs, controllers supported* * Hardware Supported: *The PCBs, controllers supported*
* Hardware Availability: *Links to where you can find this hardware* * Hardware Availability: *Links to where you can find this hardware*
Make example for this keyboard (after setting up your build environment): Make example for this keyboard (after setting up your build environment):
make %KEYBOARD%:default make %(KEYBOARD)s:default
Flashing example for this keyboard ([after setting up the bootloadHID flashing environment](https://docs.qmk.fm/#/flashing_bootloadhid)) Flashing example for this keyboard ([after setting up the bootloadHID flashing environment](https://docs.qmk.fm/#/flashing_bootloadhid))
make %KEYBOARD%:default:flash make %(KEYBOARD)s:default:flash
See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs). See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).

View File

@ -2,7 +2,7 @@
Most of our style follows PEP8 with some local modifications to make things less nit-picky. Most of our style follows PEP8 with some local modifications to make things less nit-picky.
* We target Python 3.6 for compatability with all supported platforms. * We target Python 3.7 for compatability with all supported platforms.
* We indent using four (4) spaces (soft tabs) * We indent using four (4) spaces (soft tabs)
* We encourage liberal use of comments * We encourage liberal use of comments
* Think of them as a story describing the feature * Think of them as a story describing the feature

View File

@ -1,10 +1,8 @@
"""This script automates the creation of new keyboard directories using a starter template. """This script automates the creation of new keyboard directories using a starter template.
""" """
from datetime import date from datetime import date
import fileinput
from pathlib import Path from pathlib import Path
import re import re
import shutil
from qmk.commands import git_get_username from qmk.commands import git_get_username
import qmk.path import qmk.path
@ -32,6 +30,7 @@ def validate_keyboard_name(name):
@cli.argument('-kb', '--keyboard', help='Specify the name for the new keyboard directory', arg_only=True, type=keyboard_name) @cli.argument('-kb', '--keyboard', help='Specify the name for the new keyboard directory', arg_only=True, type=keyboard_name)
@cli.argument('-t', '--type', help='Specify the keyboard type', arg_only=True, choices=KEYBOARD_TYPES) @cli.argument('-t', '--type', help='Specify the keyboard type', arg_only=True, choices=KEYBOARD_TYPES)
@cli.argument('-u', '--username', help='Specify your username (default from Git config)', arg_only=True) @cli.argument('-u', '--username', help='Specify your username (default from Git config)', arg_only=True)
@cli.argument('-n', '--realname', help='Specify your real name if you want to use that. Defaults to username', arg_only=True)
@cli.subcommand('Creates a new keyboard directory') @cli.subcommand('Creates a new keyboard directory')
def new_keyboard(cli): def new_keyboard(cli):
"""Creates a new keyboard. """Creates a new keyboard.
@ -69,7 +68,7 @@ def new_keyboard(cli):
# Get username # Get username
user_name = None user_name = None
while not user_name: while not user_name:
user_name = question('Your Name:', default=find_user_name()) user_name = question('Your GitHub User Name:', default=find_user_name())
if not user_name: if not user_name:
cli.log.error('You didn\'t provide a username, and we couldn\'t find one set in your QMK or Git configs. Please try again.') cli.log.error('You didn\'t provide a username, and we couldn\'t find one set in your QMK or Git configs. Please try again.')
@ -78,26 +77,21 @@ def new_keyboard(cli):
if cli.args.username: if cli.args.username:
return False return False
# Copy all the files real_name = None
copy_templates(keyboard_type, keyboard_path) while not real_name:
real_name = question('Your real name:', default=user_name)
# Replace all the placeholders
keyboard_basename = keyboard_path.name keyboard_basename = keyboard_path.name
replacements = [ replacements = {
('%YEAR%', str(date.today().year)), "YEAR": str(date.today().year),
('%KEYBOARD%', keyboard_basename), "KEYBOARD": keyboard_basename,
('%YOUR_NAME%', user_name), "USER_NAME": user_name,
] "YOUR_NAME": real_name,
filenames = [ }
keyboard_path / 'config.h',
keyboard_path / 'info.json', template_dir = Path('data/templates')
keyboard_path / 'readme.md', template_tree(template_dir / 'base', keyboard_path, replacements)
keyboard_path / f'{keyboard_basename}.c', template_tree(template_dir / keyboard_type, keyboard_path, replacements)
keyboard_path / f'{keyboard_basename}.h',
keyboard_path / 'keymaps/default/readme.md',
keyboard_path / 'keymaps/default/keymap.c',
]
replace_placeholders(replacements, filenames)
cli.echo('') cli.echo('')
cli.log.info(f'{{fg_green}}Created a new keyboard called {{fg_cyan}}{new_keyboard_name}{{fg_green}}.{{fg_reset}}') cli.log.info(f'{{fg_green}}Created a new keyboard called {{fg_cyan}}{new_keyboard_name}{{fg_green}}.{{fg_reset}}')
@ -114,29 +108,32 @@ def find_user_name():
return git_get_username() return git_get_username()
def copy_templates(keyboard_type, keyboard_path): def template_tree(src: Path, dst: Path, replacements: dict):
"""Copies the template files from data/templates to the new keyboard directory. """Recursively copy template and replace placeholders
Args:
src (Path)
The source folder to copy from
dst (Path)
The destination folder to copy to
replacements (dict)
a dictionary with "key":"value" pairs to replace.
Raises:
FileExistsError
When trying to overwrite existing files
""" """
template_base_path = Path('data/templates')
keyboard_basename = keyboard_path.name
cli.log.info('Copying base template files...') dst.mkdir(parents=True, exist_ok=True)
shutil.copytree(template_base_path / 'base', keyboard_path)
cli.log.info(f'Copying {{fg_cyan}}{keyboard_type}{{fg_reset}} template files...') for child in src.iterdir():
shutil.copytree(template_base_path / keyboard_type, keyboard_path, dirs_exist_ok=True) if child.is_dir():
template_tree(child, dst / child.name, replacements=replacements)
cli.log.info(f'Renaming {{fg_cyan}}keyboard.[ch]{{fg_reset}} to {{fg_cyan}}{keyboard_basename}.[ch]{{fg_reset}}...') if child.is_file():
shutil.move(keyboard_path / 'keyboard.c', keyboard_path / f'{keyboard_basename}.c') file_name = dst / (child.name % replacements)
shutil.move(keyboard_path / 'keyboard.h', keyboard_path / f'{keyboard_basename}.h')
with file_name.open(mode='x') as dst_f:
def replace_placeholders(replacements, filenames): with child.open() as src_f:
"""Replaces the given placeholders in each template file. template = src_f.read()
""" dst_f.write(template % replacements)
for replacement in replacements:
cli.log.info(f'Replacing {{fg_cyan}}{replacement[0]}{{fg_reset}} with {{fg_cyan}}{replacement[1]}{{fg_reset}}...')
with fileinput.input(files=filenames, inplace=True) as file:
for line in file:
print(line.replace(replacement[0], replacement[1]), end='')