diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/python/qmk/cli/new/keyboard.py | 79 |
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 | """ |
3 | from datetime import date | 3 | from datetime import date |
4 | import fileinput | ||
5 | from pathlib import Path | 4 | from pathlib import Path |
6 | import re | 5 | import re |
7 | import shutil | ||
8 | 6 | ||
9 | from qmk.commands import git_get_username | 7 | from qmk.commands import git_get_username |
10 | import qmk.path | 8 | import 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') |
36 | def new_keyboard(cli): | 35 | def 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 | ||
117 | def copy_templates(keyboard_type, keyboard_path): | 111 | def 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 | ||
134 | def 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) | ||