Skip to content

Commit 7ac1c54

Browse files
Marek Fialaespressif-bot
authored andcommitted
docs(tools): Updated documentation about extension options
1 parent 74f75fe commit 7ac1c54

File tree

1 file changed

+103
-0
lines changed

1 file changed

+103
-0
lines changed

docs/en/api-guides/tools/idf-py.rst

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,110 @@ Arguments from a file can be combined with additional command line arguments, an
301301

302302
A further example of how this argument file can be used, e.g., creating configuration profile files via @filename, is in the :example_file:`Multiple Build Configurations Example <build_system/cmake/multi_config/README.md>`.
303303

304+
Extending ``idf.py``
305+
====================
306+
307+
``idf.py`` can be extended with additional subcommands, global options, and callbacks provided by extension files in your project and components which participate in the build, as well as by external Python packages exposing entry points.
308+
309+
- **From components participating in the build**: Place a file named ``idf_ext.py`` in the project root or in a component's root directory that is registered in the project's ``CMakeLists.txt``. Component extensions are discovered after the project is configured - run ``idf.py build`` or ``idf.py reconfigure`` to make newly added commands available.
310+
- **From Python entry points**: Any installed Python package may contribute extensions by defining an entry point in the ``idf_extension`` group. Package installation is sufficient, no project build is required.
311+
312+
.. important::
313+
314+
Extensions must not define subcommands or options that have the same names as the core ``idf.py`` commands. Custom actions and options are checked for name collisions, overriding defaults is not possible and a warning is printed. For Python entry points, use unique identifiers as duplicate entry point names will be ignored with a warning.
315+
316+
Extension File Example
317+
----------------------
318+
319+
An extension file defines an ``action_extensions`` function which returns additional actions/options. The same structure is used for component-based extensions (``idf_ext.py``) and for package-based extensions (e.g., ``<package_name>_ext.py``):
320+
321+
.. code-block:: python
322+
323+
from typing import Any
324+
import click
325+
326+
def action_extensions(base_actions: dict, project_path: str) -> dict:
327+
def hello_test(subcommand_name: str, ctx: click.Context, global_args: dict, **action_args: Any) -> None:
328+
message = action_args.get('message')
329+
print(f"Running action: {subcommand_name}. Message: {message}")
330+
331+
def global_callback_detail(ctx: click.Context, global_args: dict, tasks: list) -> None:
332+
if getattr(global_args, 'detail', False):
333+
print(f"About to execute {len(tasks)} task(s): {[t.name for t in tasks]}")
334+
335+
return {
336+
"global_options": [
337+
{
338+
"names": ["--detail", "-d"],
339+
"is_flag": True,
340+
"help": "Enable detailed output",
341+
}
342+
],
343+
"global_action_callbacks": [global_callback_detail],
344+
"actions": {
345+
"hello": {
346+
"callback": hello_test,
347+
"short_help": "Hello from component",
348+
"help": "Test command from component extension",
349+
"options": [
350+
{
351+
"names": ["--message", "-m"],
352+
"help": "Custom message to display",
353+
"default": "Hi there!",
354+
"type": str,
355+
}
356+
]
357+
},
358+
},
359+
}
360+
361+
362+
Extension API Reference
363+
-----------------------
364+
365+
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:
366+
367+
- ``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.
368+
- ``global_action_callbacks``: A list of functions called once before any task execution. Each global action callback function accepts three arguments:
369+
370+
- ``ctx`` — the `click context`_,
371+
- ``global_args`` — all available global arguments,
372+
- ``tasks`` — the list of tasks to be executed. Task refer to the action / sub-command used with `idf.py`
373+
374+
- ``actions``: A dictionary of new subcommands. Each action has a ``callback`` function and may also include ``options``, ``arguments``, ``dependencies``, etc. Each action callback function accepts three to four arguments:
375+
376+
- ``subcommand_name`` — the name of the command (useful if multiple commands share the same callback),
377+
- ``ctx`` — the `click context`_,
378+
- ``global_args`` — all available global arguments,
379+
- ``**action_args`` — (optional) arguments passed to the action
380+
381+
Basic Usage Examples
382+
--------------------
383+
384+
1) Provide an extension from a component in your project
385+
386+
Create ``idf_ext.py`` in the project root or in a registered component (for example ``components/my_component/idf_ext.py``). Use the extension file example above as your ``idf_ext.py`` implementation.
387+
388+
Run ``idf.py build`` or ``idf.py reconfigure`` to load the new command, then ``idf.py --help`` will show the new extension.
389+
390+
2) Provide an extension via a Python package entry point
391+
392+
Implement your extension in a module named ``<package_name>_ext.py`` using the extension file example above, and expose the ``action_extensions`` function via the ``idf_extension`` entry-point group. For example, with ``pyproject.toml``:
393+
394+
.. code-block:: TOML
395+
396+
[project]
397+
name = "my_comp"
398+
version = "0.1.0"
399+
400+
[project.entry-points.idf_extension]
401+
my_pkg_ext = "my_component.my_ext:action_extensions"
402+
403+
404+
Install the package into the same Python environment as ``idf.py`` (for example with ``pip install -e .`` in the package directory). It is recommended to use a unique module name (e.g., ``<package_name>_ext.py``) to avoid name conflicts. After successful installation, ``idf.py --help`` will show the new extension.
405+
304406
.. _cmake: https://cmake.org
305407
.. _ninja: https://ninja-build.org
306408
.. _esptool.py: https://github.com/espressif/esptool/#readme
307409
.. _CCache: https://ccache.dev/
410+
.. _click context: https://click.palletsprojects.com/en/stable/api/#context

0 commit comments

Comments
 (0)