feat(tools): idf.py extension - added interface version

This commit is contained in:
Marek Fiala
2025-09-22 14:20:34 +02:00
committed by BOT
parent 7ac1c541fd
commit 96ff174dac
3 changed files with 30 additions and 1 deletions

View File

@@ -333,6 +333,7 @@ An extension file defines an ``action_extensions`` function which returns additi
print(f"About to execute {len(tasks)} task(s): {[t.name for t in tasks]}") print(f"About to execute {len(tasks)} task(s): {[t.name for t in tasks]}")
return { return {
"version": "1",
"global_options": [ "global_options": [
{ {
"names": ["--detail", "-d"], "names": ["--detail", "-d"],
@@ -362,8 +363,9 @@ An extension file defines an ``action_extensions`` function which returns additi
Extension API Reference Extension API Reference
----------------------- -----------------------
The ``action_extensions`` function takes arguments ``base_actions`` (all currently registered commands) and ``project_path`` (absolute project directory) and returns a dictionary with up to three keys: The ``action_extensions`` function takes arguments ``base_actions`` (all currently registered commands) and ``project_path`` (absolute project directory) and returns a dictionary with up to four keys:
- ``version``: A string representing the interface version of the extension. Currently, the API version is ``1``. **This key is mandatory** and must be provided.
- ``global_options``: A list of options available globally for all commands. Each option is a dictionary with fields such as ``names``, ``help``, ``type``, ``is_flag``, ``scope``, etc. - ``global_options``: A list of options available globally for all commands. Each option is a dictionary with fields such as ``names``, ``help``, ``type``, ``is_flag``, ``scope``, etc.
- ``global_action_callbacks``: A list of functions called once before any task execution. Each global action callback function accepts three arguments: - ``global_action_callbacks``: A list of functions called once before any task execution. Each global action callback function accepts three arguments:

View File

@@ -768,6 +768,12 @@ def merge_action_lists(*action_lists: dict, custom_actions: dict[str, Any] | Non
if not custom_actions: if not custom_actions:
return merged_actions return merged_actions
if not custom_actions.get('version'):
raise AttributeError(
'Attribute "version" is required in custom extension. '
'Please update your extension dictionary to contain the "version" attribute.'
)
existing_identifiers = _get_all_action_identifiers(merged_actions['actions']) existing_identifiers = _get_all_action_identifiers(merged_actions['actions'])
for name, action in custom_actions.get('actions', {}).items(): for name, action in custom_actions.get('actions', {}).items():
try: try:

View File

@@ -23,6 +23,7 @@ def action_extensions(base_actions, project_path):
return 0 return 0
return {{ return {{
'version': '1',
'global_options': [{global_options}], 'global_options': [{global_options}],
'actions': {{ 'actions': {{
{actions} {actions}
@@ -211,6 +212,26 @@ def test_extension_from_component_invalid_syntax(idf_py: IdfPyFunc, test_app_cop
ret = idf_py('--help') ret = idf_py('--help')
assert "has no attribute 'action_extensions'" in ret.stderr assert "has no attribute 'action_extensions'" in ret.stderr
idf_ext_py.write_text(
textwrap.dedent(
TEST_EXT_TEMPLATE.format(
suffix='component extension',
global_options='',
actions="""'test-component-action': {
'callback': test_extension_action,
'help': 'Test action from component extension'
}""",
)
)
)
replace_in_file(
idf_ext_py,
"'version': '1',",
'\n',
)
ret = idf_py('--help')
assert 'Attribute "version" is required in custom extension.' in ret.stderr
# ----------- Test cases for entry point extension ----------- # ----------- Test cases for entry point extension -----------