From 9835a9c83447ab3c4c31cd2b6a59639910cf3ef0 Mon Sep 17 00:00:00 2001 From: fauxpark Date: Sun, 25 Jul 2021 22:50:18 +1000 Subject: [PATCH 1/8] Port new_keyboard.sh to CLI --- lib/python/qmk/cli/new/keyboard.py | 133 +++++++++++++++++++++++++++-- lib/python/qmk/commands.py | 9 ++ util/new_keyboard.sh | 6 ++ 3 files changed, 143 insertions(+), 5 deletions(-) diff --git a/lib/python/qmk/cli/new/keyboard.py b/lib/python/qmk/cli/new/keyboard.py index ae4445ca4808..d35df486a256 100644 --- a/lib/python/qmk/cli/new/keyboard.py +++ b/lib/python/qmk/cli/new/keyboard.py @@ -1,11 +1,134 @@ -"""This script automates the creation of keyboards. +"""This script automates the creation of new keyboard directories using a starter template. """ +from datetime import date +import fileinput +from pathlib import Path +import re +import shutil + +from qmk.commands import git_get_username +import qmk.path from milc import cli +from milc.questions import choice, question + + +KEYBOARD_TYPES = ['avr', 'ps2avrgb'] + + +def keyboard_name(name): + """Callable for argparse validation. + """ + if not validate_keyboard_name(name): + raise ValueError + return name + + +def validate_keyboard_name(name): + """Returns True if the given keyboard name contains only lowercase a-z, 0-9 and underscore characters. + """ + regex = re.compile('^[a-z0-9\/_]+$') + return bool(regex.match(name)) -@cli.subcommand('Creates a new keyboard') +@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('-u', '--username', help='Specify your username (default from Git config)', arg_only=True) +@cli.subcommand('Creates a new keyboard directory') def new_keyboard(cli): - """Creates a new keyboard + """Creates a new keyboard. """ - # TODO: replace this bodge to the existing script - cli.run(['util/new_keyboard.sh'], stdin=None, capture_output=False) + cli.log.info('{style_bright}Generating a new QMK keyboard directory{style_normal}') + cli.echo('') + + # Get keyboard name + new_keyboard_name = None + while not new_keyboard_name: + new_keyboard_name = cli.args.keyboard if cli.args.keyboard else question('Keyboard Name:') + if not validate_keyboard_name(new_keyboard_name): + cli.log.error('Keyboard names must contain only {fg_cyan}lowercase a-z{fg_reset}, {fg_cyan}0-9{fg_reset}, and {fg_cyan}_{fg_reset}! Please choose a different name.') + + # Exit if passed by arg + if cli.args.keyboard: + return False + + new_keyboard_name = None + continue + + keyboard_path = qmk.path.keyboard(new_keyboard_name) + if keyboard_path.exists(): + cli.log.error(f'Keyboard {{fg_cyan}}{new_keyboard_name}{{fg_reset}} already exists! Please choose a different name.') + + # Exit if passed by arg + if cli.args.keyboard: + return False + + new_keyboard_name = None + + # Get keyboard type + keyboard_type = cli.args.type if cli.args.type else choice('Keyboard Type:', KEYBOARD_TYPES, default=0) + + # Get username + user_name = None + while not user_name: + git_username = git_get_username() + user_name = cli.args.username if cli.args.username else question('Your Name:', default=git_username) + if not user_name: + cli.log.error('You didn\'t provide a username, and we couldn\'t find one set in your Git config. Please try again.') + + # Exit if passed by arg + if cli.args.username: + return False + + # Copy all the files + copy_templates(keyboard_type, keyboard_path) + + # Replace all the placeholders + keyboard_basename = keyboard_path.name + replacements = [ + ('%YEAR%', str(date.today().year)), + ('%KEYBOARD%', keyboard_basename), + ('%YOUR_NAME%', user_name) + ] + filenames = [ + keyboard_path / 'config.h', + keyboard_path / 'info.json', + keyboard_path / 'readme.md', + keyboard_path / f'{keyboard_basename}.c', + 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.log.info(f'{{fg_green}}Created a new keyboard called {{fg_cyan}}{new_keyboard_name}{{fg_green}}.{{fg_reset}}') + cli.log.info(f'To start working on things, `cd` into {{fg_cyan}}{keyboard_path}{{fg_reset}},') + cli.log.info('or open the directory in your preferred text editor.') + + +def copy_templates(keyboard_type, keyboard_path): + """Copies the template files from quantum/template to the new keyboard directory. + """ + template_base_path = Path('quantum/template') + keyboard_basename = keyboard_path.name + + cli.log.info('Copying base template files...') + shutil.copytree(template_base_path / 'base', keyboard_path) + + cli.log.info(f'Copying {{fg_cyan}}{keyboard_type}{{fg_reset}} template files...') + shutil.copytree(template_base_path / keyboard_type, keyboard_path, dirs_exist_ok=True) + + cli.log.info(f'Renaming {{fg_cyan}}keyboard.[ch]{{fg_reset}} to {{fg_cyan}}{keyboard_basename}.[ch]{{fg_reset}}...') + shutil.move(keyboard_path / 'keyboard.c', keyboard_path / f'{keyboard_basename}.c') + shutil.move(keyboard_path / 'keyboard.h', keyboard_path / f'{keyboard_basename}.h') + + +def replace_placeholders(replacements, filenames): + """Replaces the given placeholders in each template file. + """ + 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='') diff --git a/lib/python/qmk/commands.py b/lib/python/qmk/commands.py index 8ff8501bf630..8c66228b2b7b 100644 --- a/lib/python/qmk/commands.py +++ b/lib/python/qmk/commands.py @@ -240,6 +240,15 @@ def parse_configurator_json(configurator_file): return user_keymap +def git_get_username(): + """Retrieves user's username from Git config, if set. + """ + git_username = cli.run(['git', 'config', '--get', 'user.name']) + + if git_username.returncode == 0 and git_username.stdout: + return git_username.stdout.strip() + + def git_check_repo(): """Checks that the .git directory exists inside QMK_HOME. diff --git a/util/new_keyboard.sh b/util/new_keyboard.sh index d0db23bb429b..87b7cde0c95a 100755 --- a/util/new_keyboard.sh +++ b/util/new_keyboard.sh @@ -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 From 6674a77b176dabad48be676263077c933afbd972 Mon Sep 17 00:00:00 2001 From: fauxpark Date: Sun, 25 Jul 2021 22:59:38 +1000 Subject: [PATCH 2/8] Format pass --- lib/python/qmk/cli/new/keyboard.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/python/qmk/cli/new/keyboard.py b/lib/python/qmk/cli/new/keyboard.py index d35df486a256..1822826e92b1 100644 --- a/lib/python/qmk/cli/new/keyboard.py +++ b/lib/python/qmk/cli/new/keyboard.py @@ -11,7 +11,6 @@ from milc import cli from milc.questions import choice, question - KEYBOARD_TYPES = ['avr', 'ps2avrgb'] @@ -84,12 +83,12 @@ def new_keyboard(cli): # Replace all the placeholders keyboard_basename = keyboard_path.name - replacements = [ + replacements = [ # noqa ('%YEAR%', str(date.today().year)), ('%KEYBOARD%', keyboard_basename), ('%YOUR_NAME%', user_name) ] - filenames = [ + filenames = [ # noqa keyboard_path / 'config.h', keyboard_path / 'info.json', keyboard_path / 'readme.md', From 1634073359223ec8f48b3c98619706ca00cbfd54 Mon Sep 17 00:00:00 2001 From: fauxpark Date: Sun, 25 Jul 2021 23:01:33 +1000 Subject: [PATCH 3/8] Format pass again --- lib/python/qmk/cli/new/keyboard.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/python/qmk/cli/new/keyboard.py b/lib/python/qmk/cli/new/keyboard.py index 1822826e92b1..bf2087205fa0 100644 --- a/lib/python/qmk/cli/new/keyboard.py +++ b/lib/python/qmk/cli/new/keyboard.py @@ -83,19 +83,19 @@ def new_keyboard(cli): # Replace all the placeholders keyboard_basename = keyboard_path.name - replacements = [ # noqa + replacements = [ ('%YEAR%', str(date.today().year)), ('%KEYBOARD%', keyboard_basename), - ('%YOUR_NAME%', user_name) + ('%YOUR_NAME%', user_name), ] - filenames = [ # noqa + filenames = [ keyboard_path / 'config.h', keyboard_path / 'info.json', keyboard_path / 'readme.md', keyboard_path / f'{keyboard_basename}.c', keyboard_path / f'{keyboard_basename}.h', keyboard_path / 'keymaps/default/readme.md', - keyboard_path / 'keymaps/default/keymap.c' + keyboard_path / 'keymaps/default/keymap.c', ] replace_placeholders(replacements, filenames) From bc8f387398bc02ea399cf8d3e1f82e77d27a46b0 Mon Sep 17 00:00:00 2001 From: fauxpark Date: Sun, 25 Jul 2021 23:17:40 +1000 Subject: [PATCH 4/8] Docs pass --- docs/cli_commands.md | 4 ++-- docs/es/hardware_avr.md | 38 ++++++++++++++++++++------------------ docs/hardware_avr.md | 38 ++++++++++++++++++++------------------ docs/ja/hardware_avr.md | 38 ++++++++++++++++++++------------------ 4 files changed, 62 insertions(+), 56 deletions(-) diff --git a/docs/cli_commands.md b/docs/cli_commands.md index 876ffb583102..ec24a43acbef 100644 --- a/docs/cli_commands.md +++ b/docs/cli_commands.md @@ -280,12 +280,12 @@ qmk list-keymaps -kb planck/ez This command creates a new keyboard based on available templates. -This command will prompt for input to guide you though the generation process. +Any arguments that are not provided will prompt for input. If `-u` is not passed and `user.name` is set in .gitconfig, it will be used as the default username in the prompt. **Usage**: ``` -qmk new-keyboard +qmk new-keyboard [-kb KEYBOARD] [-t {avr,ps2avrgb}] -u USERNAME ``` ## `qmk new-keymap` diff --git a/docs/es/hardware_avr.md b/docs/es/hardware_avr.md index f8c426381f2c..ac6a71565835 100644 --- a/docs/es/hardware_avr.md +++ b/docs/es/hardware_avr.md @@ -6,26 +6,28 @@ Si aún no lo has hecho, debes leer las [Pautas de teclados](hardware_keyboard_g ## Añadir tu Teclado AVR a QMK -QMK tiene varias características para simplificar el trabajo con teclados AVR. Para la mayoría de los teclados no tienes que escribir ni una sola línea de código. Para empezar, ejecuta el archivo `util/new_keyboard.sh`: +QMK tiene varias características para simplificar el trabajo con teclados AVR. Para la mayoría de los teclados no tienes que escribir ni una sola línea de código. Para empezar, ejecuta `qmk new-keyboard`: ``` -$ ./util/new_keyboard.sh -Generating a new QMK keyboard directory - -Keyboard Name: mycoolkb -Keyboard Type [avr]: -Your Name [John Smith]: - -Copying base template files... done -Copying avr template files... done -Renaming keyboard files... done -Replacing %KEYBOARD% with mycoolkb... done -Replacing %YOUR_NAME% with John Smith... done - -Created a new keyboard called mycoolkb. - -To start working on things, cd into keyboards/mycoolkb, -or open the directory in your favourite text editor. +$ qmk new-keyboard +Ψ Generating a new QMK keyboard directory + +Keyboard Name: mycoolkeeb +Keyboard Type: + 1. avr + 2. ps2avrgb +Please enter your choice: [1] +Your Name: [John Smith] +Ψ Copying base template files... +Ψ Copying avr template files... +Ψ Renaming keyboard.[ch] to mycoolkeeb.[ch]... +Ψ Replacing %YEAR% with 2021... +Ψ Replacing %KEYBOARD% with mycoolkeeb... +Ψ Replacing %YOUR_NAME% with John Smith... + +Ψ Created a new keyboard called mycoolkeeb. +Ψ To start working on things, `cd` into keyboards/mycoolkeeb, +Ψ or open the directory in your preferred text editor. ``` Esto creará todos los archivos necesarios para tu nuevo teclado, y rellenará la configuración con valores predeterminados. Ahora sólo tienes que personalizarlo para tu teclado. diff --git a/docs/hardware_avr.md b/docs/hardware_avr.md index eb536ca961a0..3d58cdc0558e 100644 --- a/docs/hardware_avr.md +++ b/docs/hardware_avr.md @@ -6,26 +6,28 @@ If you have not yet you should read the [Keyboard Guidelines](hardware_keyboard_ ## Adding Your AVR Keyboard to QMK -QMK has a number of features to simplify working with AVR keyboards. For most keyboards you don't have to write a single line of code. To get started, run the `util/new_keyboard.sh` script: +QMK has a number of features to simplify working with AVR keyboards. For most keyboards you don't have to write a single line of code. To get started, run `qmk new-keyboard`: ``` -$ ./util/new_keyboard.sh -Generating a new QMK keyboard directory - -Keyboard Name: mycoolkb -Keyboard Type [avr]: -Your Name [John Smith]: - -Copying base template files... done -Copying avr template files... done -Renaming keyboard files... done -Replacing %KEYBOARD% with mycoolkb... done -Replacing %YOUR_NAME% with John Smith... done - -Created a new keyboard called mycoolkb. - -To start working on things, cd into keyboards/mycoolkb, -or open the directory in your favourite text editor. +$ qmk new-keyboard +Ψ Generating a new QMK keyboard directory + +Keyboard Name: mycoolkeeb +Keyboard Type: + 1. avr + 2. ps2avrgb +Please enter your choice: [1] +Your Name: [John Smith] +Ψ Copying base template files... +Ψ Copying avr template files... +Ψ Renaming keyboard.[ch] to mycoolkeeb.[ch]... +Ψ Replacing %YEAR% with 2021... +Ψ Replacing %KEYBOARD% with mycoolkeeb... +Ψ Replacing %YOUR_NAME% with John Smith... + +Ψ Created a new keyboard called mycoolkeeb. +Ψ To start working on things, `cd` into keyboards/mycoolkeeb, +Ψ or open the directory in your preferred text editor. ``` This will create all the files needed to support your new keyboard, and populate the settings with default values. Now you just need to customize it for your keyboard. diff --git a/docs/ja/hardware_avr.md b/docs/ja/hardware_avr.md index 66be2f71c9a1..cdc5f8cb8662 100644 --- a/docs/ja/hardware_avr.md +++ b/docs/ja/hardware_avr.md @@ -12,26 +12,28 @@ ## AVR を使用したキーボードを QMK に追加する -QMK には AVR を使ったキーボードでの作業を簡略化するための機能が多数あります。大体のキーボードでは1行もコードを書く必要がありません。まずはじめに、`util/new_keyboard.sh` スクリプトを実行します。 +QMK には AVR を使ったキーボードでの作業を簡略化するための機能が多数あります。大体のキーボードでは1行もコードを書く必要がありません。まずはじめに、`qmk new-keyboard` を実行します。 ``` -$ ./util/new_keyboard.sh -Generating a new QMK keyboard directory - -Keyboard Name: mycoolkb -Keyboard Type [avr]: -Your Name [John Smith]: - -Copying base template files... done -Copying avr template files... done -Renaming keyboard files... done -Replacing %KEYBOARD% with mycoolkb... done -Replacing %YOUR_NAME% with John Smith... done - -Created a new keyboard called mycoolkb. - -To start working on things, cd into keyboards/mycoolkb, -or open the directory in your favourite text editor. +$ qmk new-keyboard +Ψ Generating a new QMK keyboard directory + +Keyboard Name: mycoolkeeb +Keyboard Type: + 1. avr + 2. ps2avrgb +Please enter your choice: [1] +Your Name: [John Smith] +Ψ Copying base template files... +Ψ Copying avr template files... +Ψ Renaming keyboard.[ch] to mycoolkeeb.[ch]... +Ψ Replacing %YEAR% with 2021... +Ψ Replacing %KEYBOARD% with mycoolkeeb... +Ψ Replacing %YOUR_NAME% with John Smith... + +Ψ Created a new keyboard called mycoolkeeb. +Ψ To start working on things, `cd` into keyboards/mycoolkeeb, +Ψ or open the directory in your preferred text editor. ``` これにより、新しいキーボードをサポートするために必要なすべてのファイルが作成され、デフォルト値で設定が入力されます。あとはあなたのキーボード用にカスタマイズするだけです。 From 79dffa5e1118fa7d0dcb10d13b40f1b00e39b0b1 Mon Sep 17 00:00:00 2001 From: fauxpark Date: Sun, 25 Jul 2021 23:23:21 +1000 Subject: [PATCH 5/8] Fix W605 --- lib/python/qmk/cli/new/keyboard.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/python/qmk/cli/new/keyboard.py b/lib/python/qmk/cli/new/keyboard.py index bf2087205fa0..f6ef8ceeb52b 100644 --- a/lib/python/qmk/cli/new/keyboard.py +++ b/lib/python/qmk/cli/new/keyboard.py @@ -25,7 +25,7 @@ def keyboard_name(name): def validate_keyboard_name(name): """Returns True if the given keyboard name contains only lowercase a-z, 0-9 and underscore characters. """ - regex = re.compile('^[a-z0-9\/_]+$') + regex = re.compile(r'^[a-z0-9/_]+$') return bool(regex.match(name)) From fdde0a0b374b9c1f81f9445e5f460c8b2b0127b5 Mon Sep 17 00:00:00 2001 From: Ryan Date: Mon, 26 Jul 2021 21:03:09 +1000 Subject: [PATCH 6/8] Update lib/python/qmk/cli/new/keyboard.py Co-authored-by: Erovia --- lib/python/qmk/cli/new/keyboard.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/python/qmk/cli/new/keyboard.py b/lib/python/qmk/cli/new/keyboard.py index f6ef8ceeb52b..856bd01f55d4 100644 --- a/lib/python/qmk/cli/new/keyboard.py +++ b/lib/python/qmk/cli/new/keyboard.py @@ -25,7 +25,7 @@ def keyboard_name(name): def validate_keyboard_name(name): """Returns True if the given keyboard name contains only lowercase a-z, 0-9 and underscore characters. """ - regex = re.compile(r'^[a-z0-9/_]+$') + regex = re.compile(r'^[a-z0-9][a-z0-9/_]+$') return bool(regex.match(name)) From 7985fb6c74b392657635f73a96eac0adfd282a3e Mon Sep 17 00:00:00 2001 From: fauxpark Date: Sat, 31 Jul 2021 02:37:04 +1000 Subject: [PATCH 7/8] Try arg, then config, then Git for default username --- lib/python/qmk/cli/new/keyboard.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/lib/python/qmk/cli/new/keyboard.py b/lib/python/qmk/cli/new/keyboard.py index 856bd01f55d4..b7e257497752 100644 --- a/lib/python/qmk/cli/new/keyboard.py +++ b/lib/python/qmk/cli/new/keyboard.py @@ -69,10 +69,10 @@ def new_keyboard(cli): # Get username user_name = None while not user_name: - git_username = git_get_username() - user_name = cli.args.username if cli.args.username else question('Your Name:', default=git_username) + user_name = question('Your Name:', default=find_user_name()) + if not user_name: - cli.log.error('You didn\'t provide a username, and we couldn\'t find one set in your Git config. 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.') # Exit if passed by arg if cli.args.username: @@ -104,6 +104,13 @@ def new_keyboard(cli): cli.log.info(f'To start working on things, `cd` into {{fg_cyan}}{keyboard_path}{{fg_reset}},') cli.log.info('or open the directory in your preferred text editor.') +def find_user_name(): + if cli.args.username: + return cli.args.username + elif cli.config.user.name: + return cli.config.user.name + else: + return git_get_username() def copy_templates(keyboard_type, keyboard_path): """Copies the template files from quantum/template to the new keyboard directory. From 121e1e15c5f868dafa0d5164c5e6ded0f788933a Mon Sep 17 00:00:00 2001 From: fauxpark Date: Sat, 31 Jul 2021 03:25:23 +1000 Subject: [PATCH 8/8] Formatting --- lib/python/qmk/cli/new/keyboard.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/python/qmk/cli/new/keyboard.py b/lib/python/qmk/cli/new/keyboard.py index b7e257497752..9e4232679dfc 100644 --- a/lib/python/qmk/cli/new/keyboard.py +++ b/lib/python/qmk/cli/new/keyboard.py @@ -104,6 +104,7 @@ def new_keyboard(cli): cli.log.info(f'To start working on things, `cd` into {{fg_cyan}}{keyboard_path}{{fg_reset}},') cli.log.info('or open the directory in your preferred text editor.') + def find_user_name(): if cli.args.username: return cli.args.username @@ -112,6 +113,7 @@ def find_user_name(): else: return git_get_username() + def copy_templates(keyboard_type, keyboard_path): """Copies the template files from quantum/template to the new keyboard directory. """