From 7b018f097db2d219908f74eb7a406ae5f7f93f46 Mon Sep 17 00:00:00 2001 From: Nick Brassel Date: Wed, 22 Dec 2021 05:44:47 +1100 Subject: Use the PR title rather than parsing the commit message. (#15537) --- lib/python/qmk/cli/generate/develop_pr_list.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/python') diff --git a/lib/python/qmk/cli/generate/develop_pr_list.py b/lib/python/qmk/cli/generate/develop_pr_list.py index 07e46752a6..fab0262773 100755 --- a/lib/python/qmk/cli/generate/develop_pr_list.py +++ b/lib/python/qmk/cli/generate/develop_pr_list.py @@ -97,7 +97,7 @@ def generate_develop_pr_list(cli): match = git_expr.search(line) if match: pr_info = _get_pr_info(cache, gh, match.group("pr")) - commit_info = {'hash': match.group("hash"), 'title': match.group("title"), 'pr_num': int(match.group("pr")), 'pr_labels': [label.name for label in pr_info.labels.items]} + commit_info = {'hash': match.group("hash"), 'title': pr_info['title'], 'pr_num': int(match.group("pr")), 'pr_labels': [label.name for label in pr_info.labels.items]} _categorise_commit(commit_info) def _dump_commit_list(name, collection): -- cgit v1.2.3 From 5fb93934d0f3319547cc6313845fe5a96f8b7798 Mon Sep 17 00:00:00 2001 From: Ryan Date: Thu, 6 Jan 2022 06:55:46 +1100 Subject: Fixes for bootloader refactor build failures (#15638) --- lib/python/qmk/info.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'lib/python') diff --git a/lib/python/qmk/info.py b/lib/python/qmk/info.py index 9a07fc842f..6bdf2cb166 100644 --- a/lib/python/qmk/info.py +++ b/lib/python/qmk/info.py @@ -622,12 +622,7 @@ def arm_processor_rules(info_data, rules): info_data['protocol'] = 'ChibiOS' if 'bootloader' not in info_data: - if 'STM32' in info_data['processor']: - info_data['bootloader'] = 'stm32-dfu' - elif 'WB32' in info_data['processor']: - info_data['bootloader'] = 'wb32-dfu' - else: - info_data['bootloader'] = 'unknown' + info_data['bootloader'] = 'unknown' if 'STM32' in info_data['processor']: info_data['platform'] = 'STM32' -- cgit v1.2.3 From c72ed7c02473dec4da6cb263c1e0fb2ca4856b94 Mon Sep 17 00:00:00 2001 From: Ryan Date: Mon, 17 Jan 2022 08:44:34 +1100 Subject: CLI: Parse USB device version BCD (#14580) * CLI: Parse USB device version BCD * Apply suggestions --- lib/python/qmk/cli/generate/config_h.py | 6 ++++++ lib/python/qmk/info.py | 21 +++++++++++++++++++++ 2 files changed, 27 insertions(+) (limited to 'lib/python') diff --git a/lib/python/qmk/cli/generate/config_h.py b/lib/python/qmk/cli/generate/config_h.py index f16dca1de8..6b1012fae7 100755 --- a/lib/python/qmk/cli/generate/config_h.py +++ b/lib/python/qmk/cli/generate/config_h.py @@ -108,6 +108,12 @@ def generate_config_items(kb_info_json, config_h_lines): config_h_lines.append(f'#ifndef {key}') config_h_lines.append(f'# define {key} {value}') config_h_lines.append(f'#endif // {key}') + elif key_type == 'bcd_version': + (major, minor, revision) = config_value.split('.') + config_h_lines.append('') + config_h_lines.append(f'#ifndef {config_key}') + config_h_lines.append(f'# define {config_key} 0x{major.zfill(2)}{minor}{revision}') + config_h_lines.append(f'#endif // {config_key}') else: config_h_lines.append('') config_h_lines.append(f'#ifndef {config_key}') diff --git a/lib/python/qmk/info.py b/lib/python/qmk/info.py index 6bdf2cb166..905f10ecc2 100644 --- a/lib/python/qmk/info.py +++ b/lib/python/qmk/info.py @@ -387,6 +387,19 @@ def _extract_matrix_info(info_data, config_c): return info_data +# TODO: kill off usb.device_ver in favor of usb.device_version +def _extract_device_version(info_data): + if info_data.get('usb'): + if info_data['usb'].get('device_version') and not info_data['usb'].get('device_ver'): + (major, minor, revision) = info_data['usb']['device_version'].split('.', 3) + info_data['usb']['device_ver'] = f'0x{major.zfill(2)}{minor}{revision}' + if not info_data['usb'].get('device_version') and info_data['usb'].get('device_ver'): + major = int(info_data['usb']['device_ver'][2:4]) + minor = int(info_data['usb']['device_ver'][4]) + revision = int(info_data['usb']['device_ver'][5]) + info_data['usb']['device_version'] = f'{major}.{minor}.{revision}' + + def _extract_config_h(info_data): """Pull some keyboard information from existing config.h files """ @@ -430,6 +443,13 @@ def _extract_config_h(info_data): elif key_type == 'int': dotty_info[info_key] = int(config_c[config_key]) + elif key_type == 'bcd_version': + major = int(config_c[config_key][2:4]) + minor = int(config_c[config_key][4]) + revision = int(config_c[config_key][5]) + + dotty_info[info_key] = f'{major}.{minor}.{revision}' + else: dotty_info[info_key] = config_c[config_key] @@ -444,6 +464,7 @@ def _extract_config_h(info_data): _extract_split_main(info_data, config_c) _extract_split_transport(info_data, config_c) _extract_split_right_pins(info_data, config_c) + _extract_device_version(info_data) return info_data -- cgit v1.2.3 From 77062e9a36b3167ea1ff747e5577a67969273c31 Mon Sep 17 00:00:00 2001 From: Nick Brassel Date: Mon, 24 Jan 2022 08:49:36 +1100 Subject: Add L432, L442. (#16016) --- lib/python/qmk/constants.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/python') diff --git a/lib/python/qmk/constants.py b/lib/python/qmk/constants.py index 433b110523..00e453189f 100644 --- a/lib/python/qmk/constants.py +++ b/lib/python/qmk/constants.py @@ -13,7 +13,7 @@ QMK_FIRMWARE_UPSTREAM = 'qmk/qmk_firmware' MAX_KEYBOARD_SUBFOLDERS = 5 # Supported processor types -CHIBIOS_PROCESSORS = 'cortex-m0', 'cortex-m0plus', 'cortex-m3', 'cortex-m4', 'MKL26Z64', 'MK20DX128', 'MK20DX256', 'MK66FX1M0', 'STM32F042', 'STM32F072', 'STM32F103', 'STM32F303', 'STM32F401', 'STM32F405', 'STM32F407', 'STM32F411', 'STM32F446', 'STM32G431', 'STM32G474', 'STM32L412', 'STM32L422', 'STM32L433', 'STM32L443', 'GD32VF103', 'WB32F3G71' +CHIBIOS_PROCESSORS = 'cortex-m0', 'cortex-m0plus', 'cortex-m3', 'cortex-m4', 'MKL26Z64', 'MK20DX128', 'MK20DX256', 'MK66FX1M0', 'STM32F042', 'STM32F072', 'STM32F103', 'STM32F303', 'STM32F401', 'STM32F405', 'STM32F407', 'STM32F411', 'STM32F446', 'STM32G431', 'STM32G474', 'STM32L412', 'STM32L422', 'STM32L432', 'STM32L433', 'STM32L442', 'STM32L443', 'GD32VF103', 'WB32F3G71' LUFA_PROCESSORS = 'at90usb162', 'atmega16u2', 'atmega32u2', 'atmega16u4', 'atmega32u4', 'at90usb646', 'at90usb647', 'at90usb1286', 'at90usb1287', None VUSB_PROCESSORS = 'atmega32a', 'atmega328p', 'atmega328', 'attiny85' -- cgit v1.2.3 From 6e2b03cf6901a6bbd146c074e8e9d9160358c6d9 Mon Sep 17 00:00:00 2001 From: Nick Brassel Date: Wed, 2 Feb 2022 15:30:22 +1100 Subject: Fixup multibuild filegen (#16166) * Add env variable support to multibuild. * Generate version.h in build-specific location. --- lib/python/qmk/cli/multibuild.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib/python') diff --git a/lib/python/qmk/cli/multibuild.py b/lib/python/qmk/cli/multibuild.py index 85ed0fa1e9..ad059edff3 100755 --- a/lib/python/qmk/cli/multibuild.py +++ b/lib/python/qmk/cli/multibuild.py @@ -32,6 +32,7 @@ def _is_split(keyboard_name): @cli.argument('-c', '--clean', arg_only=True, action='store_true', help="Remove object files before compiling.") @cli.argument('-f', '--filter', arg_only=True, action='append', default=[], help="Filter the list of keyboards based on the supplied value in rules.mk. Supported format is 'SPLIT_KEYBOARD=yes'. May be passed multiple times.") @cli.argument('-km', '--keymap', type=str, default='default', help="The keymap name to build. Default is 'default'.") +@cli.argument('-e', '--env', arg_only=True, action='append', default=[], help="Set a variable to be passed to make. May be passed multiple times.") @cli.subcommand('Compile QMK Firmware for all keyboards.', hidden=False if cli.config.user.developer else True) def multibuild(cli): """Compile QMK Firmware against all keyboards. @@ -68,7 +69,7 @@ def multibuild(cli): all: {keyboard_safe}_binary {keyboard_safe}_binary: @rm -f "{QMK_FIRMWARE}/.build/failed.log.{keyboard_safe}" || true - +@$(MAKE) -C "{QMK_FIRMWARE}" -f "{QMK_FIRMWARE}/build_keyboard.mk" KEYBOARD="{keyboard_name}" KEYMAP="{cli.args.keymap}" REQUIRE_PLATFORM_KEY= COLOR=true SILENT=false \\ + +@$(MAKE) -C "{QMK_FIRMWARE}" -f "{QMK_FIRMWARE}/build_keyboard.mk" KEYBOARD="{keyboard_name}" KEYMAP="{cli.args.keymap}" REQUIRE_PLATFORM_KEY= COLOR=true SILENT=false {' '.join(cli.args.env)} \\ >>"{QMK_FIRMWARE}/.build/build.log.{os.getpid()}.{keyboard_safe}" 2>&1 \\ || cp "{QMK_FIRMWARE}/.build/build.log.{os.getpid()}.{keyboard_safe}" "{QMK_FIRMWARE}/.build/failed.log.{os.getpid()}.{keyboard_safe}" @{{ grep '\[ERRORS\]' "{QMK_FIRMWARE}/.build/build.log.{os.getpid()}.{keyboard_safe}" >/dev/null 2>&1 && printf "Build %-64s \e[1;31m[ERRORS]\e[0m\\n" "{keyboard_name}:{cli.args.keymap}" ; }} \\ -- cgit v1.2.3 From d4dc743a85641dd74c708aa12fb78b91035cc802 Mon Sep 17 00:00:00 2001 From: Drashna Jaelre Date: Tue, 1 Feb 2022 20:44:42 -0800 Subject: Fix issues with Python Tests (#16162) * Reformat python due to yapf changes * Fix pytest keymap list test * revert formatting * Use contra, because, well https://www.reddit.com/r/MechanicalKeyboards/comments/8riofq/did_i_kill_my_contra/ --- lib/python/qmk/tests/test_cli_commands.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/python') diff --git a/lib/python/qmk/tests/test_cli_commands.py b/lib/python/qmk/tests/test_cli_commands.py index 2973f81702..54b143c64f 100644 --- a/lib/python/qmk/tests/test_cli_commands.py +++ b/lib/python/qmk/tests/test_cli_commands.py @@ -113,7 +113,7 @@ def test_list_keymaps_community(): def test_list_keymaps_kb_only(): - result = check_subcommand('list-keymaps', '-kb', 'niu_mini') + result = check_subcommand('list-keymaps', '-kb', 'contra') check_returncode(result) assert 'default' and 'via' in result.stdout -- cgit v1.2.3 From db43e450771f4eefe27821a88cc86df46c1006c1 Mon Sep 17 00:00:00 2001 From: Nick Brassel Date: Fri, 4 Feb 2022 07:36:02 +1100 Subject: Ensure `version.h` is recreated each build. (#16188) --- lib/python/qmk/cli/generate/version_h.py | 3 +++ 1 file changed, 3 insertions(+) (limited to 'lib/python') diff --git a/lib/python/qmk/cli/generate/version_h.py b/lib/python/qmk/cli/generate/version_h.py index b8e52588c4..69341e36f0 100644 --- a/lib/python/qmk/cli/generate/version_h.py +++ b/lib/python/qmk/cli/generate/version_h.py @@ -20,6 +20,9 @@ def generate_version_h(cli): version_h = create_version_h(cli.args.skip_git, cli.args.skip_all) if cli.args.output: + cli.args.output.parent.mkdir(parents=True, exist_ok=True) + if cli.args.output.exists(): + cli.args.output.replace(cli.args.output.parent / (cli.args.output.name + '.bak')) cli.args.output.write_text(version_h) if not cli.args.quiet: -- cgit v1.2.3 From 8fd8b2dc92a01b86a8e9ff3c37baeba760312140 Mon Sep 17 00:00:00 2001 From: Nick Brassel Date: Sat, 5 Feb 2022 07:36:57 +1100 Subject: Skip categorisation of PR if it's only for code formatting. (#16215) --- lib/python/qmk/cli/generate/develop_pr_list.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'lib/python') diff --git a/lib/python/qmk/cli/generate/develop_pr_list.py b/lib/python/qmk/cli/generate/develop_pr_list.py index fab0262773..09236a7c42 100755 --- a/lib/python/qmk/cli/generate/develop_pr_list.py +++ b/lib/python/qmk/cli/generate/develop_pr_list.py @@ -12,6 +12,14 @@ fix_expr = re.compile(r'fix', flags=re.IGNORECASE) clean1_expr = re.compile(r'\[(develop|keyboard|keymap|core|cli|bug|docs|feature)\]', flags=re.IGNORECASE) clean2_expr = re.compile(r'^(develop|keyboard|keymap|core|cli|bug|docs|feature):', flags=re.IGNORECASE) +ignored_titles = ["Format code according to conventions"] + + +def _is_ignored(title): + for ignore in ignored_titles: + if ignore in title: + return + def _get_pr_info(cache, gh, pr_num): pull = cache.get(f'pull:{pr_num}') @@ -81,7 +89,9 @@ def generate_develop_pr_list(cli): else: normal_collection.append(info) - if "dependencies" in commit_info['pr_labels']: + if _is_ignored(commit_info['title']): + return + elif "dependencies" in commit_info['pr_labels']: fix_or_normal(commit_info, pr_list_bugs, pr_list_dependencies) elif "core" in commit_info['pr_labels']: fix_or_normal(commit_info, pr_list_bugs, pr_list_core) -- cgit v1.2.3 From 2e279f1b889a59156f30524cc83358f64ee53287 Mon Sep 17 00:00:00 2001 From: Joel Challis Date: Tue, 8 Feb 2022 19:03:30 +0000 Subject: Initial pass at data driven new-keyboard subcommand (#12795) * Initial pass at a data driven keyboard subcommand * format * lint * Handle bootloader now its mandatory --- lib/python/qmk/cli/new/keyboard.py | 293 ++++++++++++++++++++++++++----------- lib/python/qmk/path.py | 2 +- 2 files changed, 206 insertions(+), 89 deletions(-) (limited to 'lib/python') diff --git a/lib/python/qmk/cli/new/keyboard.py b/lib/python/qmk/cli/new/keyboard.py index 4093b8c90d..59e781a932 100644 --- a/lib/python/qmk/cli/new/keyboard.py +++ b/lib/python/qmk/cli/new/keyboard.py @@ -1,15 +1,82 @@ """This script automates the creation of new keyboard directories using a starter template. """ +import re +import json +import shutil from datetime import date from pathlib import Path -import re +from dotty_dict import dotty -from qmk.commands import git_get_username -import qmk.path from milc import cli from milc.questions import choice, question -KEYBOARD_TYPES = ['avr', 'ps2avrgb'] +from qmk.commands import git_get_username +from qmk.json_schema import load_jsonschema +from qmk.path import keyboard +from qmk.json_encoders import InfoJSONEncoder +from qmk.json_schema import deep_update + +COMMUNITY = Path('layouts/default/') +TEMPLATE = Path('data/templates/keyboard/') + +MCU2BOOTLOADER = { + "MKL26Z64": "halfkay", + "MK20DX128": "halfkay", + "MK20DX256": "halfkay", + "MK66FX1M0": "halfkay", + "STM32F042": "stm32-dfu", + "STM32F072": "stm32-dfu", + "STM32F103": "stm32duino", + "STM32F303": "stm32-dfu", + "STM32F401": "stm32-dfu", + "STM32F405": "stm32-dfu", + "STM32F407": "stm32-dfu", + "STM32F411": "stm32-dfu", + "STM32F446": "stm32-dfu", + "STM32G431": "stm32-dfu", + "STM32G474": "stm32-dfu", + "STM32L412": "stm32-dfu", + "STM32L422": "stm32-dfu", + "STM32L432": "stm32-dfu", + "STM32L433": "stm32-dfu", + "STM32L442": "stm32-dfu", + "STM32L443": "stm32-dfu", + "GD32VF103": "gd32v-dfu", + "WB32F3G71": "wb32-dfu", + "atmega16u2": "atmel-dfu", + "atmega32u2": "atmel-dfu", + "atmega16u4": "atmel-dfu", + "atmega32u4": "atmel-dfu", + "at90usb162": "atmel-dfu", + "at90usb646": "atmel-dfu", + "at90usb647": "atmel-dfu", + "at90usb1286": "atmel-dfu", + "at90usb1287": "atmel-dfu", + "atmega32a": "bootloadhid", + "atmega328p": "usbasploader", + "atmega328": "usbasploader", +} + +# defaults +schema = dotty(load_jsonschema('keyboard')) +mcu_types = sorted(schema["properties.processor.enum"], key=str.casefold) +available_layouts = sorted([x.name for x in COMMUNITY.iterdir() if x.is_dir()]) + + +def mcu_type(mcu): + """Callable for argparse validation. + """ + if mcu not in mcu_types: + raise ValueError + return mcu + + +def layout_type(layout): + """Callable for argparse validation. + """ + if layout not in available_layouts: + raise ValueError + return layout def keyboard_name(name): @@ -27,113 +94,163 @@ def validate_keyboard_name(name): return bool(regex.match(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('-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') -def new_keyboard(cli): - """Creates a new keyboard. +def select_default_bootloader(mcu): + """Provide sane defaults for bootloader """ - cli.log.info('{style_bright}Generating a new QMK keyboard directory{style_normal}') - cli.echo('') + return MCU2BOOTLOADER.get(mcu, "custom") + + +def replace_placeholders(src, dest, tokens): + """Replaces the given placeholders in each template file. + """ + content = src.read_text() + for key, value in tokens.items(): + content = content.replace(f'%{key}%', value) - # 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.') + dest.write_text(content) - # Exit if passed by arg - if cli.args.keyboard: - return False - new_keyboard_name = None - continue +def augment_community_info(src, dest): + """Splice in any additional data into info.json + """ + info = json.loads(src.read_text()) + template = json.loads(dest.read_text()) - 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.') + # merge community with template + deep_update(info, template) - # Exit if passed by arg - if cli.args.keyboard: - return False + # avoid assumptions on macro name by using the first available + first_layout = next(iter(info["layouts"].values()))["layout"] - new_keyboard_name = None + # guess at width and height now its optional + width, height = (0, 0) + for item in first_layout: + width = max(width, int(item["x"]) + 1) + height = max(height, int(item["y"]) + 1) - # Get keyboard type - keyboard_type = cli.args.type if cli.args.type else choice('Keyboard Type:', KEYBOARD_TYPES, default=0) + info["matrix_pins"] = { + "cols": ["C2"] * width, + "rows": ["D1"] * height, + } - # Get username - user_name = None - while not user_name: - user_name = question('Your GitHub User Name:', default=find_user_name()) + # assume a 1:1 mapping on matrix to electrical + for item in first_layout: + item["matrix"] = [int(item["y"]), int(item["x"])] - 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.') + # finally write out the updated info.json + dest.write_text(json.dumps(info, cls=InfoJSONEncoder)) - # Exit if passed by arg - if cli.args.username: - return False - real_name = None - while not real_name: - real_name = question('Your real name:', default=user_name) +def prompt_keyboard(): + prompt = """{fg_yellow}Name Your Keyboard Project{style_reset_all} - keyboard_basename = keyboard_path.name - replacements = { - "YEAR": str(date.today().year), - "KEYBOARD": keyboard_basename, - "USER_NAME": user_name, - "YOUR_NAME": real_name, - } +For more infomation, see: +https://docs.qmk.fm/#/hardware_keyboard_guidelines?id=naming-your-keyboardproject - template_dir = Path('data/templates') - template_tree(template_dir / 'base', keyboard_path, replacements) - template_tree(template_dir / keyboard_type, keyboard_path, replacements) +keyboard Name? """ + + return question(prompt, validate=lambda x: not keyboard(x).exists()) - 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 prompt_user(): + prompt = """{fg_yellow}Attribution{style_reset_all} -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() +Used for maintainer, copyright, etc +Your GitHub Username? """ + return question(prompt, default=git_get_username()) -def template_tree(src: Path, dst: Path, replacements: dict): - """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. +def prompt_name(def_name): + prompt = """{fg_yellow}More Attribution{style_reset_all} - Raises: - FileExistsError - When trying to overwrite existing files +Used for maintainer, copyright, etc + +Your Real Name? """ + return question(prompt, default=def_name) + + +def prompt_layout(): + prompt = """{fg_yellow}Pick Base Layout{style_reset_all} + +As a starting point, one of the common layouts can be used to bootstrap the process + +Default Layout? """ + # avoid overwhelming user - remove some? + filtered_layouts = [x for x in available_layouts if not any(xs in x for xs in ['_split', '_blocker', '_tsangan', '_f13'])] + filtered_layouts.append("none of the above") + + return choice(prompt, filtered_layouts, default=len(filtered_layouts) - 1) + + +def prompt_mcu(): + prompt = """{fg_yellow}What Powers Your Project{style_reset_all} + +For more infomation, see: +https://docs.qmk.fm/#/compatible_microcontrollers + +MCU? """ + # remove any options strictly used for compatibility + filtered_mcu = [x for x in mcu_types if not any(xs in x for xs in ['cortex', 'unknown'])] + + return choice(prompt, filtered_mcu, default=filtered_mcu.index("atmega32u4")) + + +@cli.argument('-kb', '--keyboard', help='Specify the name for the new keyboard directory', arg_only=True, type=keyboard_name) +@cli.argument('-l', '--layout', help='Community layout to bootstrap with', arg_only=True, type=layout_type) +@cli.argument('-t', '--type', help='Specify the keyboard MCU type', arg_only=True, type=mcu_type) +@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') +def new_keyboard(cli): + """Creates a new keyboard. """ + cli.log.info('{style_bright}Generating a new QMK keyboard directory{style_normal}') + cli.echo('') + + kb_name = cli.args.keyboard if cli.args.keyboard else prompt_keyboard() + user_name = cli.args.username if cli.args.username else prompt_user() + real_name = cli.args.realname or cli.args.username if cli.args.realname or cli.args.username else prompt_name(user_name) + default_layout = cli.args.layout if cli.args.layout else prompt_layout() + mcu = cli.args.type if cli.args.type else prompt_mcu() + bootloader = select_default_bootloader(mcu) - dst.mkdir(parents=True, exist_ok=True) + if not validate_keyboard_name(kb_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.') + return 1 - for child in src.iterdir(): - if child.is_dir(): - template_tree(child, dst / child.name, replacements=replacements) + if keyboard(kb_name).exists(): + cli.log.error(f'Keyboard {{fg_cyan}}{kb_name}{{fg_reset}} already exists! Please choose a different name.') + return 1 - if child.is_file(): - file_name = dst / (child.name % replacements) + tokens = {'YEAR': str(date.today().year), 'KEYBOARD': kb_name, 'USER_NAME': user_name, 'REAL_NAME': real_name, 'LAYOUT': default_layout, 'MCU': mcu, 'BOOTLOADER': bootloader} - with file_name.open(mode='x') as dst_f: - with child.open() as src_f: - template = src_f.read() - dst_f.write(template % replacements) + if cli.config.general.verbose: + cli.log.info("Creating keyboard with:") + for key, value in tokens.items(): + cli.echo(f" {key.ljust(10)}: {value}") + + # TODO: detach community layout and rename to just "LAYOUT" + if default_layout == 'none of the above': + default_layout = "ortho_4x4" + + # begin with making the deepest folder in the tree + keymaps_path = keyboard(kb_name) / 'keymaps/' + keymaps_path.mkdir(parents=True) + + # copy in keymap.c or keymap.json + community_keymap = Path(COMMUNITY / f'{default_layout}/default_{default_layout}/') + shutil.copytree(community_keymap, keymaps_path / 'default') + + # process template files + for file in list(TEMPLATE.iterdir()): + replace_placeholders(file, keyboard(kb_name) / file.name, tokens) + + # merge in infos + community_info = Path(COMMUNITY / f'{default_layout}/info.json') + augment_community_info(community_info, keyboard(kb_name) / community_info.name) + + cli.log.info(f'{{fg_green}}Created a new keyboard called {{fg_cyan}}{kb_name}{{fg_green}}.{{fg_reset}}') + cli.log.info(f'To start working on things, `cd` into {{fg_cyan}}keyboards/{kb_name}{{fg_reset}},') + cli.log.info('or open the directory in your preferred text editor.') + cli.log.info(f"And build with {{fg_yellow}}qmk compile -kb {kb_name} -km default{{fg_reset}}.") diff --git a/lib/python/qmk/path.py b/lib/python/qmk/path.py index 72bae59273..dfb8371f84 100644 --- a/lib/python/qmk/path.py +++ b/lib/python/qmk/path.py @@ -46,7 +46,7 @@ def keymap(keyboard_name): """ keyboard_folder = keyboard(keyboard_name) - for i in range(MAX_KEYBOARD_SUBFOLDERS): + for _ in range(MAX_KEYBOARD_SUBFOLDERS): if (keyboard_folder / 'keymaps').exists(): return (keyboard_folder / 'keymaps').resolve() -- cgit v1.2.3 From f7e7671f691cfd42f322198f04690727f6493d73 Mon Sep 17 00:00:00 2001 From: Joel Challis Date: Thu, 10 Feb 2022 17:45:51 +0000 Subject: Migrate more makefile utilities to builddefs sub-directory (#16002) --- lib/python/qmk/cli/multibuild.py | 2 +- lib/python/qmk/commands.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/python') diff --git a/lib/python/qmk/cli/multibuild.py b/lib/python/qmk/cli/multibuild.py index ad059edff3..dff8c88422 100755 --- a/lib/python/qmk/cli/multibuild.py +++ b/lib/python/qmk/cli/multibuild.py @@ -69,7 +69,7 @@ def multibuild(cli): all: {keyboard_safe}_binary {keyboard_safe}_binary: @rm -f "{QMK_FIRMWARE}/.build/failed.log.{keyboard_safe}" || true - +@$(MAKE) -C "{QMK_FIRMWARE}" -f "{QMK_FIRMWARE}/build_keyboard.mk" KEYBOARD="{keyboard_name}" KEYMAP="{cli.args.keymap}" REQUIRE_PLATFORM_KEY= COLOR=true SILENT=false {' '.join(cli.args.env)} \\ + +@$(MAKE) -C "{QMK_FIRMWARE}" -f "{QMK_FIRMWARE}/builddefs/build_keyboard.mk" KEYBOARD="{keyboard_name}" KEYMAP="{cli.args.keymap}" REQUIRE_PLATFORM_KEY= COLOR=true SILENT=false {' '.join(cli.args.env)} \\ >>"{QMK_FIRMWARE}/.build/build.log.{os.getpid()}.{keyboard_safe}" 2>&1 \\ || cp "{QMK_FIRMWARE}/.build/build.log.{os.getpid()}.{keyboard_safe}" "{QMK_FIRMWARE}/.build/failed.log.{os.getpid()}.{keyboard_safe}" @{{ grep '\[ERRORS\]' "{QMK_FIRMWARE}/.build/build.log.{os.getpid()}.{keyboard_safe}" >/dev/null 2>&1 && printf "Build %-64s \e[1;31m[ERRORS]\e[0m\\n" "{keyboard_name}:{cli.args.keymap}" ; }} \\ diff --git a/lib/python/qmk/commands.py b/lib/python/qmk/commands.py index 90a68ca3cd..275cd72e5c 100644 --- a/lib/python/qmk/commands.py +++ b/lib/python/qmk/commands.py @@ -213,7 +213,7 @@ def compile_configurator_json(user_keymap, bootloader=None, parallel=1, **env_va '-r', '-R', '-f', - 'build_keyboard.mk', + 'builddefs/build_keyboard.mk', ]) if bootloader: -- cgit v1.2.3 From 23c238a1807c3e8c3bdd4eb432506a1469640df5 Mon Sep 17 00:00:00 2001 From: Erovia Date: Mon, 14 Feb 2022 11:02:35 +0000 Subject: CLI: Minor additions #12795 (#16276) --- lib/python/qmk/cli/new/keyboard.py | 89 ++++++++++++++++---------------------- lib/python/qmk/constants.py | 39 +++++++++++++++++ 2 files changed, 76 insertions(+), 52 deletions(-) (limited to 'lib/python') diff --git a/lib/python/qmk/cli/new/keyboard.py b/lib/python/qmk/cli/new/keyboard.py index 59e781a932..8596994d38 100644 --- a/lib/python/qmk/cli/new/keyboard.py +++ b/lib/python/qmk/cli/new/keyboard.py @@ -15,48 +15,11 @@ from qmk.json_schema import load_jsonschema from qmk.path import keyboard from qmk.json_encoders import InfoJSONEncoder from qmk.json_schema import deep_update +from qmk.constants import MCU2BOOTLOADER COMMUNITY = Path('layouts/default/') TEMPLATE = Path('data/templates/keyboard/') -MCU2BOOTLOADER = { - "MKL26Z64": "halfkay", - "MK20DX128": "halfkay", - "MK20DX256": "halfkay", - "MK66FX1M0": "halfkay", - "STM32F042": "stm32-dfu", - "STM32F072": "stm32-dfu", - "STM32F103": "stm32duino", - "STM32F303": "stm32-dfu", - "STM32F401": "stm32-dfu", - "STM32F405": "stm32-dfu", - "STM32F407": "stm32-dfu", - "STM32F411": "stm32-dfu", - "STM32F446": "stm32-dfu", - "STM32G431": "stm32-dfu", - "STM32G474": "stm32-dfu", - "STM32L412": "stm32-dfu", - "STM32L422": "stm32-dfu", - "STM32L432": "stm32-dfu", - "STM32L433": "stm32-dfu", - "STM32L442": "stm32-dfu", - "STM32L443": "stm32-dfu", - "GD32VF103": "gd32v-dfu", - "WB32F3G71": "wb32-dfu", - "atmega16u2": "atmel-dfu", - "atmega32u2": "atmel-dfu", - "atmega16u4": "atmel-dfu", - "atmega32u4": "atmel-dfu", - "at90usb162": "atmel-dfu", - "at90usb646": "atmel-dfu", - "at90usb647": "atmel-dfu", - "at90usb1286": "atmel-dfu", - "at90usb1287": "atmel-dfu", - "atmega32a": "bootloadhid", - "atmega328p": "usbasploader", - "atmega328": "usbasploader", -} - # defaults schema = dotty(load_jsonschema('keyboard')) mcu_types = sorted(schema["properties.processor.enum"], key=str.casefold) @@ -141,20 +104,42 @@ def augment_community_info(src, dest): dest.write_text(json.dumps(info, cls=InfoJSONEncoder)) +def _question(*args, **kwargs): + """Ugly workaround until 'milc' learns to display a repromt msg + """ + # TODO: Remove this once milc.questions.question handles reprompt messages + + reprompt = kwargs["reprompt"] + del kwargs["reprompt"] + validate = kwargs["validate"] + del kwargs["validate"] + + prompt = args[0] + ret = None + while not ret: + ret = question(prompt, **kwargs) + if not validate(ret): + ret = None + prompt = reprompt + + return ret + + def prompt_keyboard(): prompt = """{fg_yellow}Name Your Keyboard Project{style_reset_all} - For more infomation, see: https://docs.qmk.fm/#/hardware_keyboard_guidelines?id=naming-your-keyboardproject -keyboard Name? """ +Keyboard Name? """ - return question(prompt, validate=lambda x: not keyboard(x).exists()) + errmsg = 'Keyboard already exists! Please choose a different name:' + return _question(prompt, reprompt=errmsg, validate=lambda x: not keyboard(x).exists()) -def prompt_user(): - prompt = """{fg_yellow}Attribution{style_reset_all} +def prompt_user(): + prompt = """ +{fg_yellow}Attribution{style_reset_all} Used for maintainer, copyright, etc Your GitHub Username? """ @@ -162,8 +147,8 @@ Your GitHub Username? """ def prompt_name(def_name): - prompt = """{fg_yellow}More Attribution{style_reset_all} - + prompt = """ +{fg_yellow}More Attribution{style_reset_all} Used for maintainer, copyright, etc Your Real Name? """ @@ -171,8 +156,8 @@ Your Real Name? """ def prompt_layout(): - prompt = """{fg_yellow}Pick Base Layout{style_reset_all} - + prompt = """ +{fg_yellow}Pick Base Layout{style_reset_all} As a starting point, one of the common layouts can be used to bootstrap the process Default Layout? """ @@ -184,8 +169,8 @@ Default Layout? """ def prompt_mcu(): - prompt = """{fg_yellow}What Powers Your Project{style_reset_all} - + prompt = """ +{fg_yellow}What Powers Your Project{style_reset_all} For more infomation, see: https://docs.qmk.fm/#/compatible_microcontrollers @@ -199,7 +184,7 @@ MCU? """ @cli.argument('-kb', '--keyboard', help='Specify the name for the new keyboard directory', arg_only=True, type=keyboard_name) @cli.argument('-l', '--layout', help='Community layout to bootstrap with', arg_only=True, type=layout_type) @cli.argument('-t', '--type', help='Specify the keyboard MCU type', arg_only=True, type=mcu_type) -@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)', dest='name') @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') def new_keyboard(cli): @@ -209,8 +194,8 @@ def new_keyboard(cli): cli.echo('') kb_name = cli.args.keyboard if cli.args.keyboard else prompt_keyboard() - user_name = cli.args.username if cli.args.username else prompt_user() - real_name = cli.args.realname or cli.args.username if cli.args.realname or cli.args.username else prompt_name(user_name) + user_name = cli.config.new_keyboard.name if cli.config.new_keyboard.name else prompt_user() + real_name = cli.args.realname or cli.config.new_keyboard.name if cli.args.realname or cli.config.new_keyboard.name else prompt_name(user_name) default_layout = cli.args.layout if cli.args.layout else prompt_layout() mcu = cli.args.type if cli.args.type else prompt_mcu() bootloader = select_default_bootloader(mcu) diff --git a/lib/python/qmk/constants.py b/lib/python/qmk/constants.py index 00e453189f..e4b699cdb1 100644 --- a/lib/python/qmk/constants.py +++ b/lib/python/qmk/constants.py @@ -17,6 +17,45 @@ CHIBIOS_PROCESSORS = 'cortex-m0', 'cortex-m0plus', 'cortex-m3', 'cortex-m4', 'MK LUFA_PROCESSORS = 'at90usb162', 'atmega16u2', 'atmega32u2', 'atmega16u4', 'atmega32u4', 'at90usb646', 'at90usb647', 'at90usb1286', 'at90usb1287', None VUSB_PROCESSORS = 'atmega32a', 'atmega328p', 'atmega328', 'attiny85' +# Bootloaders of the supported processors +MCU2BOOTLOADER = { + "MKL26Z64": "halfkay", + "MK20DX128": "halfkay", + "MK20DX256": "halfkay", + "MK66FX1M0": "halfkay", + "STM32F042": "stm32-dfu", + "STM32F072": "stm32-dfu", + "STM32F103": "stm32duino", + "STM32F303": "stm32-dfu", + "STM32F401": "stm32-dfu", + "STM32F405": "stm32-dfu", + "STM32F407": "stm32-dfu", + "STM32F411": "stm32-dfu", + "STM32F446": "stm32-dfu", + "STM32G431": "stm32-dfu", + "STM32G474": "stm32-dfu", + "STM32L412": "stm32-dfu", + "STM32L422": "stm32-dfu", + "STM32L432": "stm32-dfu", + "STM32L433": "stm32-dfu", + "STM32L442": "stm32-dfu", + "STM32L443": "stm32-dfu", + "GD32VF103": "gd32v-dfu", + "WB32F3G71": "wb32-dfu", + "atmega16u2": "atmel-dfu", + "atmega32u2": "atmel-dfu", + "atmega16u4": "atmel-dfu", + "atmega32u4": "atmel-dfu", + "at90usb162": "atmel-dfu", + "at90usb646": "atmel-dfu", + "at90usb647": "atmel-dfu", + "at90usb1286": "atmel-dfu", + "at90usb1287": "atmel-dfu", + "atmega32a": "bootloadhid", + "atmega328p": "usbasploader", + "atmega328": "usbasploader", +} + # Common format strings DATE_FORMAT = '%Y-%m-%d' DATETIME_FORMAT = '%Y-%m-%d %H:%M:%S %Z' -- cgit v1.2.3 From b0621223bc53f634a28243b874379e8e157878fd Mon Sep 17 00:00:00 2001 From: Joel Challis Date: Tue, 15 Feb 2022 01:42:58 +0000 Subject: Various fixes for new-keyboard (#16358) --- lib/python/qmk/cli/new/keyboard.py | 10 +++++++++- lib/python/qmk/info.py | 1 + 2 files changed, 10 insertions(+), 1 deletion(-) (limited to 'lib/python') diff --git a/lib/python/qmk/cli/new/keyboard.py b/lib/python/qmk/cli/new/keyboard.py index 8596994d38..6fa9ad5b2c 100644 --- a/lib/python/qmk/cli/new/keyboard.py +++ b/lib/python/qmk/cli/new/keyboard.py @@ -208,7 +208,15 @@ def new_keyboard(cli): cli.log.error(f'Keyboard {{fg_cyan}}{kb_name}{{fg_reset}} already exists! Please choose a different name.') return 1 - tokens = {'YEAR': str(date.today().year), 'KEYBOARD': kb_name, 'USER_NAME': user_name, 'REAL_NAME': real_name, 'LAYOUT': default_layout, 'MCU': mcu, 'BOOTLOADER': bootloader} + tokens = { # Comment here is to force multiline formatting + 'YEAR': str(date.today().year), + 'KEYBOARD': kb_name, + 'USER_NAME': user_name, + 'REAL_NAME': real_name, + 'LAYOUT': default_layout, + 'MCU': mcu, + 'BOOTLOADER': bootloader + } if cli.config.general.verbose: cli.log.info("Creating keyboard with:") diff --git a/lib/python/qmk/info.py b/lib/python/qmk/info.py index 905f10ecc2..7e6f531f9c 100644 --- a/lib/python/qmk/info.py +++ b/lib/python/qmk/info.py @@ -49,6 +49,7 @@ def info_json(keyboard): 'parse_errors': [], 'parse_warnings': [], 'maintainer': 'qmk', + 'manufacturer': 'qmk', } # Populate the list of JSON keymaps -- cgit v1.2.3 From cf31355f08dca311a013168eb3eb995e2fc6a3d1 Mon Sep 17 00:00:00 2001 From: Joel Challis Date: Wed, 23 Feb 2022 17:33:08 +0000 Subject: Changelog 2022q1 (#16380) * Initial changelog pass * update generate-develop-pr-list content * Fix bad word-ness * Fix generate-develop-pr-list ignores * Update docs/ChangeLog/20220226.md Co-authored-by: Sergey Vlasov Co-authored-by: Sergey Vlasov --- lib/python/qmk/cli/generate/develop_pr_list.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib/python') diff --git a/lib/python/qmk/cli/generate/develop_pr_list.py b/lib/python/qmk/cli/generate/develop_pr_list.py index 09236a7c42..549db5b185 100755 --- a/lib/python/qmk/cli/generate/develop_pr_list.py +++ b/lib/python/qmk/cli/generate/develop_pr_list.py @@ -18,7 +18,8 @@ ignored_titles = ["Format code according to conventions"] def _is_ignored(title): for ignore in ignored_titles: if ignore in title: - return + return True + return False def _get_pr_info(cache, gh, pr_num): -- cgit v1.2.3