Align client/docs gen with recent changes

This commit is contained in:
zvecr 2022-10-16 20:24:37 +01:00
parent e8f40517a8
commit 9fcab705a9
22 changed files with 309 additions and 137 deletions

View File

@ -1,14 +1,17 @@
{{ constants.GPL2_HEADER_SH_LIKE }}
{{ constants.GENERATED_HEADER_SH_LIKE }}
from enum import IntEnum
# version: 0.0.1
class RgblightModes(IntEnum):
{%- for id, effect in constants.rgblight.effects | dictsort %}
{%- for id, effect in specs.rgblight.effects | dictsort %}
{{ effect.key }} = {{ id }}
{%- endfor %}
# version: 0.0.1
class RgbMatrixModes(IntEnum):
{%- for id, effect in constants.rgb_matrix.effects | dictsort %}
{%- for id, effect in specs.rgb_matrix.effects | dictsort %}
{{ effect.key }} = {{ id }}
{%- endfor %}

View File

@ -1,4 +1,5 @@
{{ constants.GPL2_HEADER_SH_LIKE }}
{{ constants.GENERATED_HEADER_SH_LIKE }}
class XAPRouteError(Exception):
pass

View File

@ -1,3 +1,5 @@
{{ constants.GPL2_HEADER_SH_LIKE }}
{{ constants.GENERATED_HEADER_SH_LIKE }}
from collections import namedtuple
from enum import IntFlag, IntEnum
from struct import Struct

View File

@ -1,3 +1,5 @@
{{ constants.GPL2_HEADER_XML_LIKE }}
{{ constants.GENERATED_HEADER_XML_LIKE }}
{%- for item in xap.documentation.order -%}
{%- if not item[0:1] == '!' -%}
{{ xap.documentation.get(item) }}

View File

@ -1,8 +0,0 @@
{%- if route.request_type == 'struct' -%}
__Request:__
{%- for member in route.request_struct_members -%}
<br>{{ "&nbsp;"|safe*4 }}* {{ member.name }}: `{{ member.type }}`
{%- endfor -%}
{%- elif route.request_type -%}
__Request:__ `{{ route.request_type }}`
{%- endif -%}

View File

@ -1,8 +0,0 @@
{%- if route.return_type == 'struct' -%}
__Response:__
{%- for member in route.return_struct_members -%}
<br>{{ "&nbsp;"|safe*4 }}* {{ member.name }}: `{{ member.type }}`
{%- endfor -%}
{%- elif route.return_type -%}
__Response:__ `{{ route.return_type }}`
{%- endif -%}

View File

@ -1,3 +1,22 @@
{%- macro gen_payload(name, type, members) -%}
{%- if type == 'struct' -%}
__{{ name }}:__
{%- for member in members -%}
<br>{{ "&nbsp;"|safe*4 }}* {{ member.name }}: `{{ member.type }}`
{%- endfor -%}
{%- elif type -%}
__{{ name }}:__ `{{ type }}`
{%- endif -%}
{%- endmacro -%}
{%- macro gen_payloads(route) -%}
{{ gen_payload('Request', route.request_type, route.request_struct_members) }}{%- if route.return_type and route.request_type -%}<br><br>{% endif %}{{ gen_payload('Response', route.return_type, route.return_struct_members) }}
{%- endmacro -%}
{%- macro gen_tags(route) -%}
{% if 'secure' == route.permissions %}__Secure__{% endif %}
{%- endmacro -%}
{%- for id, route in xap.routes | dictsort %}
### {{ route.name }} - `{{ id }}`
{{ route.description }}
@ -7,9 +26,7 @@
| -- | -- | -- | -- | -- |
{%- for subid, subroute in route.routes | dictsort %}
{%- if not subroute.routes %}
{%- with route=subroute %}
| {{ subroute.name }} | `{{ id }} {{ subid }}` | {% if 'secure' == subroute.permissions %}__Secure__{% endif %} | {%- include 'route_request.md.j2' -%}{%- if subroute.return_type and subroute.request_type -%}<br><br>{% endif %}{%- include 'route_response.md.j2' -%} | {{ subroute.description.replace('\n', '<br>') }}|
{%- endwith %}
| {{ subroute.name }} | `{{ id }} {{ subid }}` | {{ gen_tags(subroute) }} | {{ gen_payloads(subroute) }} | {{ subroute.description | newline_to_br }}|
{%- endif %}
{%- endfor %}
@ -23,9 +40,7 @@
| -- | -- | -- | -- | -- |
{%- for subsubid, subsubroute in subroute.routes | dictsort %}
{%- if not subsubroute.routes %}
{%- with route=subsubroute %}
| {{ subsubroute.name }} | `{{ id }} {{ subid }} {{ subsubid }}` | {% if 'secure' == subsubroute.permissions %}__Secure__{% endif %} | {%- include 'route_request.md.j2' -%}{%- if subsubroute.return_type and subsubroute.request_type -%}<br><br>{% endif %}{%- include 'route_response.md.j2' -%} | {{ subsubroute.description.replace('\n', '<br>') }}|
{%- endwith %}
| {{ subsubroute.name }} | `{{ id }} {{ subid }} {{ subsubid }}` | {{ gen_tags(subsubroute) }} | {{ gen_payloads(subsubroute) }} | {{ subsubroute.description | newline_to_br }}|
{%- endif %}
{%- endfor %}
{%- endif %}

View File

@ -0,0 +1,6 @@
{{ constants.GPL2_HEADER_XML_LIKE }}
{{ constants.GENERATED_HEADER_XML_LIKE }}
{%- for ver in versions | reverse -%}
* [XAP Version {{ ver }}](xap_{{ ver }}.md)
{% endfor %}

View File

@ -1,5 +1,5 @@
{{ GPL2_HEADER_C_LIKE }}
{{ GENERATED_HEADER_C_LIKE }}
{{ constants.GPL2_HEADER_C_LIKE }}
{{ constants.GENERATED_HEADER_C_LIKE }}
#pragma once
#include <stdint.h>

View File

@ -1,5 +1,5 @@
{{ GPL2_HEADER_C_LIKE }}
{{ GENERATED_HEADER_C_LIKE }}
{{ constants.GPL2_HEADER_C_LIKE }}
{{ constants.GENERATED_HEADER_C_LIKE }}
////////////////////////////////////////////////////////////////////////////////
// Full XAP {{ xap.version }} definitions

View File

@ -1,3 +1,29 @@
<!--- Copyright 2022 QMK --->
<!--- SPDX-License-Identifier: GPL-2.0-or-later --->
<!---
*******************************************************************************
88888888888 888 d8b .d888 d8b 888 d8b
888 888 Y8P d88P" Y8P 888 Y8P
888 888 888 888
888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b
888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K
888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b.
888 888 888 888 X88 888 888 888 Y8b. 888 X88
888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P'
888 888
888 888
888 888
.d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888
d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888
888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888
Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888
"Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888
888
Y8b d88P
"Y88P"
*******************************************************************************
--->
# QMK Firmware XAP Specs
This document describes the requirements of the QMK XAP ("extensible application protocol") API.

View File

@ -1,3 +1,29 @@
<!--- Copyright 2022 QMK --->
<!--- SPDX-License-Identifier: GPL-2.0-or-later --->
<!---
*******************************************************************************
88888888888 888 d8b .d888 d8b 888 d8b
888 888 Y8P d88P" Y8P 888 Y8P
888 888 888 888
888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b
888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K
888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b.
888 888 888 888 X88 888 888 888 Y8b. 888 X88
888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P'
888 888
888 888
888 888
.d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888
d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888
888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888
Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888
"Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888
888
Y8b d88P
"Y88P"
*******************************************************************************
--->
# QMK Firmware XAP Specs
This document describes the requirements of the QMK XAP ("extensible application protocol") API.

View File

@ -1,3 +1,29 @@
<!--- Copyright 2022 QMK --->
<!--- SPDX-License-Identifier: GPL-2.0-or-later --->
<!---
*******************************************************************************
88888888888 888 d8b .d888 d8b 888 d8b
888 888 Y8P d88P" Y8P 888 Y8P
888 888 888 888
888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b
888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K
888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b.
888 888 888 888 X88 888 888 888 Y8b. 888 X88
888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P'
888 888
888 888
888 888
.d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888
d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888
888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888
Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888
"Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888
888
Y8b d88P
"Y88P"
*******************************************************************************
--->
# QMK Firmware XAP Specs
This document describes the requirements of the QMK XAP ("extensible application protocol") API.

View File

@ -1,3 +1,29 @@
<!--- Copyright 2022 QMK --->
<!--- SPDX-License-Identifier: GPL-2.0-or-later --->
<!---
*******************************************************************************
88888888888 888 d8b .d888 d8b 888 d8b
888 888 Y8P d88P" Y8P 888 Y8P
888 888 888 888
888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b
888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K
888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b.
888 888 888 888 X88 888 888 888 Y8b. 888 X88
888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P'
888 888
888 888
888 888
.d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888
d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888
888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888
Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888
"Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888
888
Y8b d88P
"Y88P"
*******************************************************************************
--->
# QMK Firmware XAP Specs
This document describes the requirements of the QMK XAP ("extensible application protocol") API.

View File

@ -1,4 +1,29 @@
<!-- This file is generated -->
<!--- Copyright 2022 QMK --->
<!--- SPDX-License-Identifier: GPL-2.0-or-later --->
<!---
*******************************************************************************
88888888888 888 d8b .d888 d8b 888 d8b
888 888 Y8P d88P" Y8P 888 Y8P
888 888 888 888
888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b
888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K
888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b.
888 888 888 888 X88 888 888 888 Y8b. 888 X88
888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P'
888 888
888 888
888 888
.d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888
d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888
888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888
Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888
"Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888
888
Y8b d88P
"Y88P"
*******************************************************************************
--->
* [XAP Version 0.3.0](xap_0.3.0.md)
* [XAP Version 0.2.0](xap_0.2.0.md)
* [XAP Version 0.1.0](xap_0.1.0.md)

View File

@ -1,16 +1,18 @@
"""This script generates the XAP protocol documentation.
"""
import hjson
from milc import cli
from qmk.constants import QMK_FIRMWARE
from qmk.xap.common import get_xap_definition_files, update_xap_definitions, render_xap_output
from milc import cli
@cli.subcommand('Generates the XAP protocol documentation.', hidden=False if cli.config.user.developer else True)
def xap_generate_docs(cli):
"""Generates the XAP protocol documentation by merging the definitions files, and producing the corresponding Markdown document under `/docs/`.
"""
docs_list = []
versions = []
overall = None
for file in get_xap_definition_files():
@ -22,17 +24,12 @@ def xap_generate_docs(cli):
overall['response_flags']['bits'][str(n)] = {'name': '', 'description': '', 'define': '-'}
output_doc = QMK_FIRMWARE / "docs" / f"{file.stem}.md"
docs_list.append(output_doc)
versions.append(overall['version'])
output = render_xap_output('docs', 'docs.md.j2', overall)
with open(output_doc, "w", encoding='utf-8') as out_file:
out_file.write(output)
output_doc = QMK_FIRMWARE / "docs" / "xap_protocol.md"
output = render_xap_output('docs', 'versions.md.j2', overall, versions=versions)
with open(output_doc, "w", encoding='utf-8') as out_file:
out_file.write('''\
<!-- This file is generated -->
''')
for file in reversed(sorted(docs_list)):
ver = file.stem[4:]
out_file.write(f'* [XAP Version {ver}]({file.name})\n')
out_file.write(output)

View File

@ -1,12 +1,11 @@
"""This script generates the python XAP client.
"""
from qmk.constants import QMK_FIRMWARE, GPL2_HEADER_SH_LIKE, GENERATED_HEADER_SH_LIKE
from qmk.xap.common import latest_xap_defs, render_xap_output
from qmk.commands import dump_lines
from milc import cli
from qmk.commands import dump_lines
from qmk.constants import QMK_FIRMWARE
from qmk.xap.common import latest_xap_defs, render_xap_output
@cli.subcommand('Generates the python XAP client.', hidden=False if cli.config.user.developer else True)
def xap_generate_python(cli):
@ -14,9 +13,7 @@ def xap_generate_python(cli):
parent = QMK_FIRMWARE / 'lib' / 'python' / 'xap_client'
for name in ['types.py', 'routes.py', 'constants.py']:
lines = [GPL2_HEADER_SH_LIKE, GENERATED_HEADER_SH_LIKE]
output = render_xap_output('client/python', f'{name}.j2', defs)
lines += output.split('\n')
lines = output.split('\n')
dump_lines(parent / name, lines)

View File

@ -136,6 +136,11 @@ GPL2_HEADER_SH_LIKE = f'''\
# SPDX-License-Identifier: GPL-2.0-or-later
'''
GPL2_HEADER_XML_LIKE = f'''\
<!--- Copyright {date.today().year} QMK --->
<!--- SPDX-License-Identifier: GPL-2.0-or-later --->
'''
GENERATED_HEADER_C_LIKE = '''\
/*******************************************************************************
88888888888 888 d8b .d888 d8b 888 d8b
@ -186,3 +191,29 @@ GENERATED_HEADER_SH_LIKE = '''\
#
################################################################################
'''
GENERATED_HEADER_XML_LIKE = '''\
<!---
*******************************************************************************
88888888888 888 d8b .d888 d8b 888 d8b
888 888 Y8P d88P" Y8P 888 Y8P
888 888 888 888
888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b
888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K
888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b.
888 888 888 888 X88 888 888 888 Y8b. 888 X88
888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P'
888 888
888 888
888 888
.d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888
d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888
888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888
Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888
"Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888
888
Y8b d88P
"Y88P"
*******************************************************************************
--->
'''

View File

@ -8,7 +8,7 @@ from pathlib import Path
from typing import OrderedDict
from jinja2 import Environment, FileSystemLoader, select_autoescape
from qmk.constants import QMK_FIRMWARE, GPL2_HEADER_C_LIKE, GENERATED_HEADER_C_LIKE
import qmk.constants
from qmk.git import git_get_version
from qmk.json_schema import json_load, validate
from qmk.decorators import lru_cache
@ -53,7 +53,7 @@ def load_lighting_spec(feature, version='latest'):
def _get_jinja2_env(data_templates_xap_subdir: str):
templates_dir = os.path.join(QMK_FIRMWARE, 'data', 'templates', 'xap', data_templates_xap_subdir)
templates_dir = os.path.join(qmk.constants.QMK_FIRMWARE, 'data', 'templates', 'xap', data_templates_xap_subdir)
j2 = Environment(loader=FileSystemLoader(templates_dir), autoescape=select_autoescape())
return j2
@ -65,11 +65,11 @@ def render_xap_output(data_templates_xap_subdir, file_to_render, defs=None, **kw
attach_filters(j2)
constants = {}
specs = {}
for feature in ['rgblight', 'rgb_matrix', 'led_matrix']:
constants[feature] = load_lighting_spec(feature)
specs[feature] = load_lighting_spec(feature)
return j2.get_template(file_to_render).render(xap=defs, qmk_version=git_get_version(), xap_str=hjson.dumps(defs), constants=constants, GPL2_HEADER_C_LIKE=GPL2_HEADER_C_LIKE, GENERATED_HEADER_C_LIKE=GENERATED_HEADER_C_LIKE, **kwargs)
return j2.get_template(file_to_render).render(xap=defs, qmk_version=git_get_version(), xap_str=hjson.dumps(defs), specs=specs, constants=qmk.constants, **kwargs)
def _find_kb_spec(kb):
@ -130,7 +130,7 @@ def _merge_ordered_dicts(dicts):
def get_xap_definition_files():
"""Get the sorted list of XAP definition files, from <QMK>/data/xap.
"""
xap_defs = QMK_FIRMWARE / "data" / "xap"
xap_defs = qmk.constants.QMK_FIRMWARE / "data" / "xap"
return list(sorted(xap_defs.glob('**/xap_*.hjson')))

View File

@ -61,8 +61,13 @@ def _triplet_to_bcd(value: str):
return f'0x{int(m.group(1)):02d}{int(m.group(2)):02d}{int(m.group(3)):04d}'
def _newline_to_br(value: str):
return value.replace('\n', '<br>')
def attach_filters(j2: Environment):
j2.filters['to_snake'] = to_snake
j2.filters['newline_to_br'] = _newline_to_br
j2.filters['triplet_to_bcd'] = _triplet_to_bcd
j2.filters['fnv1a_32'] = _fnv1a_32
j2.filters['type_to_c'] = _xap_type_to_c

View File

@ -75,6 +75,7 @@ class RgblightModes(IntEnum):
TWINKLE_6 = 0x29
# version: 0.0.1
class RgbMatrixModes(IntEnum):
SOLID_COLOR = 0x00
ALPHAS_MODS = 0x01

View File

@ -26,7 +26,6 @@
#
################################################################################
class XAPRouteError(Exception):
pass