aboutsummaryrefslogtreecommitdiff
path: root/lib/python
diff options
context:
space:
mode:
Diffstat (limited to 'lib/python')
-rw-r--r--lib/python/qmk/cli/new/keyboard.py79
1 files changed, 38 insertions, 41 deletions
diff --git a/lib/python/qmk/cli/new/keyboard.py b/lib/python/qmk/cli/new/keyboard.py
index 369d2bd7d..4093b8c90 100644
--- a/lib/python/qmk/cli/new/keyboard.py
+++ b/lib/python/qmk/cli/new/keyboard.py
@@ -1,10 +1,8 @@
1"""This script automates the creation of new keyboard directories using a starter template. 1"""This script automates the creation of new keyboard directories using a starter template.
2""" 2"""
3from datetime import date 3from datetime import date
4import fileinput
5from pathlib import Path 4from pathlib import Path
6import re 5import re
7import shutil
8 6
9from qmk.commands import git_get_username 7from qmk.commands import git_get_username
10import qmk.path 8import qmk.path
@@ -32,6 +30,7 @@ def validate_keyboard_name(name):
32@cli.argument('-kb', '--keyboard', help='Specify the name for the new keyboard directory', arg_only=True, type=keyboard_name) 30@cli.argument('-kb', '--keyboard', help='Specify the name for the new keyboard directory', arg_only=True, type=keyboard_name)
33@cli.argument('-t', '--type', help='Specify the keyboard type', arg_only=True, choices=KEYBOARD_TYPES) 31@cli.argument('-t', '--type', help='Specify the keyboard type', arg_only=True, choices=KEYBOARD_TYPES)
34@cli.argument('-u', '--username', help='Specify your username (default from Git config)', arg_only=True) 32@cli.argument('-u', '--username', help='Specify your username (default from Git config)', arg_only=True)
33@cli.argument('-n', '--realname', help='Specify your real name if you want to use that. Defaults to username', arg_only=True)
35@cli.subcommand('Creates a new keyboard directory') 34@cli.subcommand('Creates a new keyboard directory')
36def new_keyboard(cli): 35def new_keyboard(cli):
37 """Creates a new keyboard. 36 """Creates a new keyboard.
@@ -69,7 +68,7 @@ def new_keyboard(cli):
69 # Get username 68 # Get username
70 user_name = None 69 user_name = None
71 while not user_name: 70 while not user_name:
72 user_name = question('Your Name:', default=find_user_name()) 71 user_name = question('Your GitHub User Name:', default=find_user_name())
73 72
74 if not user_name: 73 if not user_name:
75 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.') 74 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):
78 if cli.args.username: 77 if cli.args.username:
79 return False 78 return False
80 79
81 # Copy all the files 80 real_name = None
82 copy_templates(keyboard_type, keyboard_path) 81 while not real_name:
82 real_name = question('Your real name:', default=user_name)
83 83
84 # Replace all the placeholders
85 keyboard_basename = keyboard_path.name 84 keyboard_basename = keyboard_path.name
86 replacements = [ 85 replacements = {
87 ('%YEAR%', str(date.today().year)), 86 "YEAR": str(date.today().year),
88 ('%KEYBOARD%', keyboard_basename), 87 "KEYBOARD": keyboard_basename,
89 ('%YOUR_NAME%', user_name), 88 "USER_NAME": user_name,
90 ] 89 "YOUR_NAME": real_name,
91 filenames = [ 90 }
92 keyboard_path / 'config.h', 91
93 keyboard_path / 'info.json', 92 template_dir = Path('data/templates')
94 keyboard_path / 'readme.md', 93 template_tree(template_dir / 'base', keyboard_path, replacements)
95 keyboard_path / f'{keyboard_basename}.c', 94 template_tree(template_dir / keyboard_type, keyboard_path, replacements)
96 keyboard_path / f'{keyboard_basename}.h',
97 keyboard_path / 'keymaps/default/readme.md',
98 keyboard_path / 'keymaps/default/keymap.c',
99 ]
100 replace_placeholders(replacements, filenames)
101 95
102 cli.echo('') 96 cli.echo('')
103 cli.log.info(f'{{fg_green}}Created a new keyboard called {{fg_cyan}}{new_keyboard_name}{{fg_green}}.{{fg_reset}}') 97 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():
114 return git_get_username() 108 return git_get_username()
115 109
116 110
117def copy_templates(keyboard_type, keyboard_path): 111def template_tree(src: Path, dst: Path, replacements: dict):
118 """Copies the template files from data/templates to the new keyboard directory. 112 """Recursively copy template and replace placeholders
119 """
120 template_base_path = Path('data/templates')
121 keyboard_basename = keyboard_path.name
122 113
123 cli.log.info('Copying base template files...') 114 Args:
124 shutil.copytree(template_base_path / 'base', keyboard_path) 115 src (Path)
116 The source folder to copy from
117 dst (Path)
118 The destination folder to copy to
119 replacements (dict)
120 a dictionary with "key":"value" pairs to replace.
125 121
126 cli.log.info(f'Copying {{fg_cyan}}{keyboard_type}{{fg_reset}} template files...') 122 Raises:
127 shutil.copytree(template_base_path / keyboard_type, keyboard_path, dirs_exist_ok=True) 123 FileExistsError
124 When trying to overwrite existing files
125 """
128 126
129 cli.log.info(f'Renaming {{fg_cyan}}keyboard.[ch]{{fg_reset}} to {{fg_cyan}}{keyboard_basename}.[ch]{{fg_reset}}...') 127 dst.mkdir(parents=True, exist_ok=True)
130 shutil.move(keyboard_path / 'keyboard.c', keyboard_path / f'{keyboard_basename}.c')
131 shutil.move(keyboard_path / 'keyboard.h', keyboard_path / f'{keyboard_basename}.h')
132 128
129 for child in src.iterdir():
130 if child.is_dir():
131 template_tree(child, dst / child.name, replacements=replacements)
133 132
134def replace_placeholders(replacements, filenames): 133 if child.is_file():
135 """Replaces the given placeholders in each template file. 134 file_name = dst / (child.name % replacements)
136 """
137 for replacement in replacements:
138 cli.log.info(f'Replacing {{fg_cyan}}{replacement[0]}{{fg_reset}} with {{fg_cyan}}{replacement[1]}{{fg_reset}}...')
139 135
140 with fileinput.input(files=filenames, inplace=True) as file: 136 with file_name.open(mode='x') as dst_f:
141 for line in file: 137 with child.open() as src_f:
142 print(line.replace(replacement[0], replacement[1]), end='') 138 template = src_f.read()
139 dst_f.write(template % replacements)