Example #1
0
def generate_api(cli):
    """Generates the QMK API data.
    """
    api_data_dir = Path('api_data')
    v1_dir = api_data_dir / 'v1'
    keyboard_list = v1_dir / 'keyboard_list.json'
    keyboard_all = v1_dir / 'keyboards.json'
    usb_file = v1_dir / 'usb.json'

    if not api_data_dir.exists():
        api_data_dir.mkdir()

    kb_all = {'last_updated': current_datetime(), 'keyboards': {}}
    usb_list = {'last_updated': current_datetime(), 'devices': {}}

    # Generate and write keyboard specific JSON files
    for keyboard_name in list_keyboards():
        kb_all['keyboards'][keyboard_name] = info_json(keyboard_name)
        keyboard_dir = v1_dir / 'keyboards' / keyboard_name
        keyboard_info = keyboard_dir / 'info.json'
        keyboard_readme = keyboard_dir / 'readme.md'
        keyboard_readme_src = Path('keyboards') / keyboard_name / 'readme.md'

        keyboard_dir.mkdir(parents=True, exist_ok=True)
        keyboard_info.write_text(
            json.dumps({
                'last_updated': current_datetime(),
                'keyboards': {
                    keyboard_name: kb_all['keyboards'][keyboard_name]
                }
            }))

        if keyboard_readme_src.exists():
            copyfile(keyboard_readme_src, keyboard_readme)

        if 'usb' in kb_all['keyboards'][keyboard_name]:
            usb = kb_all['keyboards'][keyboard_name]['usb']

            if 'vid' in usb and usb['vid'] not in usb_list['devices']:
                usb_list['devices'][usb['vid']] = {}

            if 'pid' in usb and usb['pid'] not in usb_list['devices'][
                    usb['vid']]:
                usb_list['devices'][usb['vid']][usb['pid']] = {}

            if 'vid' in usb and 'pid' in usb:
                usb_list['devices'][usb['vid']][
                    usb['pid']][keyboard_name] = usb

    # Write the global JSON files
    keyboard_list.write_text(
        json.dumps(
            {
                'last_updated': current_datetime(),
                'keyboards': sorted(kb_all['keyboards'])
            },
            cls=InfoJSONEncoder))
    keyboard_all.write_text(json.dumps(kb_all, cls=InfoJSONEncoder))
    usb_file.write_text(json.dumps(usb_list, cls=InfoJSONEncoder))
Example #2
0
def lint(cli):
    """Check keyboard and keymap for common mistakes.
    """
    failed = []

    # Determine our keyboard list
    if cli.args.all_kb:
        if cli.args.keyboard:
            cli.log.warning(
                'Both --all-kb and --keyboard passed, --all-kb takes precedence.'
            )

        keyboard_list = list_keyboards()
    elif not cli.config.lint.keyboard:
        cli.log.error('Missing required arguments: --keyboard or --all-kb')
        cli.print_help()
        return False
    else:
        keyboard_list = cli.config.lint.keyboard.split(',')

    # Lint each keyboard
    for kb in keyboard_list:
        if not is_keyboard(kb):
            cli.log.error('No such keyboard: %s', kb)
            continue

        # Determine keymaps to also check
        if cli.args.all_km:
            keymaps = list_keymaps(kb)
        elif cli.config.lint.keymap:
            keymaps = {cli.config.lint.keymap}
        else:
            keymaps = _list_defaultish_keymaps(kb)
            # Ensure that at least a 'default' keymap always exists
            keymaps.add('default')

        ok = True

        # keyboard level checks
        if not keyboard_check(kb):
            ok = False

        # Keymap specific checks
        for keymap in keymaps:
            if not keymap_check(kb, keymap):
                ok = False

        # Report status
        if not ok:
            failed.append(kb)

    # Check and report the overall status
    if failed:
        cli.log.error('Lint check failed for: %s', ', '.join(failed))
        return False

    cli.log.info('Lint check passed!')
    return True
Example #3
0
def generate_api(cli):
    """Generates the QMK API data.
    """
    api_data_dir = Path('api_data')
    v1_dir = api_data_dir / 'v1'
    keyboard_all_file = v1_dir / 'keyboards.json'  # A massive JSON containing everything
    keyboard_list_file = v1_dir / 'keyboard_list.json'  # A simple list of keyboard targets
    keyboard_aliases_file = v1_dir / 'keyboard_aliases.json'  # A list of historical keyboard names and their new name
    keyboard_metadata_file = v1_dir / 'keyboard_metadata.json'  # All the data configurator/via needs for initialization
    usb_file = v1_dir / 'usb.json'  # A mapping of USB VID/PID -> keyboard target

    if not api_data_dir.exists():
        api_data_dir.mkdir()

    kb_all = {}
    usb_list = {}

    # Generate and write keyboard specific JSON files
    for keyboard_name in list_keyboards():
        kb_all[keyboard_name] = info_json(keyboard_name)
        keyboard_dir = v1_dir / 'keyboards' / keyboard_name
        keyboard_info = keyboard_dir / 'info.json'
        keyboard_readme = keyboard_dir / 'readme.md'
        keyboard_readme_src = find_readme(keyboard_name)

        keyboard_dir.mkdir(parents=True, exist_ok=True)
        keyboard_json = json.dumps({'last_updated': current_datetime(), 'keyboards': {keyboard_name: kb_all[keyboard_name]}})
        if not cli.args.dry_run:
            keyboard_info.write_text(keyboard_json)
            cli.log.debug('Wrote file %s', keyboard_info)

            if keyboard_readme_src:
                copyfile(keyboard_readme_src, keyboard_readme)
                cli.log.debug('Copied %s -> %s', keyboard_readme_src, keyboard_readme)

        if 'usb' in kb_all[keyboard_name]:
            usb = kb_all[keyboard_name]['usb']

            if 'vid' in usb and usb['vid'] not in usb_list:
                usb_list[usb['vid']] = {}

            if 'pid' in usb and usb['pid'] not in usb_list[usb['vid']]:
                usb_list[usb['vid']][usb['pid']] = {}

            if 'vid' in usb and 'pid' in usb:
                usb_list[usb['vid']][usb['pid']][keyboard_name] = usb

    # Generate data for the global files
    keyboard_list = sorted(kb_all)
    keyboard_aliases = json_load(Path('data/mappings/keyboard_aliases.json'))
    keyboard_metadata = {
        'last_updated': current_datetime(),
        'keyboards': keyboard_list,
        'keyboard_aliases': keyboard_aliases,
        'usb': usb_list,
    }

    # Write the global JSON files
    keyboard_all_json = json.dumps({'last_updated': current_datetime(), 'keyboards': kb_all}, cls=InfoJSONEncoder)
    usb_json = json.dumps({'last_updated': current_datetime(), 'usb': usb_list}, cls=InfoJSONEncoder)
    keyboard_list_json = json.dumps({'last_updated': current_datetime(), 'keyboards': keyboard_list}, cls=InfoJSONEncoder)
    keyboard_aliases_json = json.dumps({'last_updated': current_datetime(), 'keyboard_aliases': keyboard_aliases}, cls=InfoJSONEncoder)
    keyboard_metadata_json = json.dumps(keyboard_metadata, cls=InfoJSONEncoder)

    if not cli.args.dry_run:
        keyboard_all_file.write_text(keyboard_all_json)
        usb_file.write_text(usb_json)
        keyboard_list_file.write_text(keyboard_list_json)
        keyboard_aliases_file.write_text(keyboard_aliases_json)
        keyboard_metadata_file.write_text(keyboard_metadata_json)
Example #4
0
def lint(cli):
    """Check keyboard and keymap for common mistakes.
    """
    failed = []

    # Determine our keyboard list
    if cli.args.all_kb:
        if cli.args.keyboard:
            cli.log.warning('Both --all-kb and --keyboard passed, --all-kb takes presidence.')

        keyboard_list = list_keyboards()
    elif not cli.config.lint.keyboard:
        cli.log.error('Missing required arguments: --keyboard or --all-kb')
        cli.print_help()
        return False
    else:
        keyboard_list = cli.config.lint.keyboard.split(',')

    # Lint each keyboard
    for kb in keyboard_list:
        if not is_keyboard(kb):
            cli.log.error('No such keyboard: %s', kb)
            continue

        # Gather data about the keyboard.
        ok = True
        keyboard_path = keyboard(kb)
        keyboard_info = info_json(kb)

        # Check for errors in the info.json
        if keyboard_info['parse_errors']:
            ok = False
            cli.log.error('%s: Errors found when generating info.json.', kb)

        if cli.config.lint.strict and keyboard_info['parse_warnings']:
            ok = False
            cli.log.error('%s: Warnings found when generating info.json (Strict mode enabled.)', kb)

        # Check the rules.mk file(s)
        rules_mk_assignment_errors = rules_mk_assignment_only(keyboard_path)
        if rules_mk_assignment_errors:
            ok = False
            cli.log.error('%s: Non-assignment code found in rules.mk. Move it to post_rules.mk instead.', kb)
            for assignment_error in rules_mk_assignment_errors:
                cli.log.error(assignment_error)

        # Keymap specific checks
        if cli.config.lint.keymap:
            if not keymap_check(kb, cli.config.lint.keymap):
                ok = False

        # Report status
        if not ok:
            failed.append(kb)

    # Check and report the overall status
    if failed:
        cli.log.error('Lint check failed for: %s', ', '.join(failed))
        return False

    cli.log.info('Lint check passed!')
    return True