idf-build-apps 2.13.3__tar.gz → 2.15.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. {idf_build_apps-2.13.3 → idf_build_apps-2.15.0}/.github/workflows/publish-pypi.yml +1 -1
  2. {idf_build_apps-2.13.3 → idf_build_apps-2.15.0}/.github/workflows/sync-jira.yml +2 -2
  3. {idf_build_apps-2.13.3 → idf_build_apps-2.15.0}/.github/workflows/test-build-docs.yml +1 -1
  4. {idf_build_apps-2.13.3 → idf_build_apps-2.15.0}/.github/workflows/test-build-idf-apps.yml +10 -6
  5. {idf_build_apps-2.13.3 → idf_build_apps-2.15.0}/.pre-commit-config.yaml +3 -3
  6. {idf_build_apps-2.13.3 → idf_build_apps-2.15.0}/CHANGELOG.md +67 -2
  7. {idf_build_apps-2.13.3 → idf_build_apps-2.15.0}/PKG-INFO +1 -1
  8. {idf_build_apps-2.13.3 → idf_build_apps-2.15.0}/docs/conf_common.py +1 -1
  9. {idf_build_apps-2.13.3 → idf_build_apps-2.15.0}/docs/en/conf.py +1 -1
  10. {idf_build_apps-2.13.3 → idf_build_apps-2.15.0}/docs/en/explanations/dependency_driven_build.rst +11 -0
  11. {idf_build_apps-2.13.3 → idf_build_apps-2.15.0}/docs/en/references/manifest.rst +9 -0
  12. {idf_build_apps-2.13.3 → idf_build_apps-2.15.0}/idf_build_apps/__init__.py +2 -2
  13. {idf_build_apps-2.13.3 → idf_build_apps-2.15.0}/idf_build_apps/__main__.py +1 -1
  14. {idf_build_apps-2.13.3 → idf_build_apps-2.15.0}/idf_build_apps/app.py +14 -6
  15. {idf_build_apps-2.13.3 → idf_build_apps-2.15.0}/idf_build_apps/args.py +15 -1
  16. {idf_build_apps-2.13.3 → idf_build_apps-2.15.0}/idf_build_apps/autocompletions.py +1 -1
  17. {idf_build_apps-2.13.3 → idf_build_apps-2.15.0}/idf_build_apps/constants.py +1 -1
  18. {idf_build_apps-2.13.3 → idf_build_apps-2.15.0}/idf_build_apps/finder.py +1 -1
  19. {idf_build_apps-2.13.3 → idf_build_apps-2.15.0}/idf_build_apps/junit/__init__.py +1 -1
  20. {idf_build_apps-2.13.3 → idf_build_apps-2.15.0}/idf_build_apps/junit/report.py +1 -1
  21. {idf_build_apps-2.13.3 → idf_build_apps-2.15.0}/idf_build_apps/junit/utils.py +1 -1
  22. {idf_build_apps-2.13.3 → idf_build_apps-2.15.0}/idf_build_apps/log.py +1 -1
  23. {idf_build_apps-2.13.3 → idf_build_apps-2.15.0}/idf_build_apps/main.py +15 -6
  24. {idf_build_apps-2.13.3 → idf_build_apps-2.15.0}/idf_build_apps/manifest/__init__.py +1 -1
  25. {idf_build_apps-2.13.3 → idf_build_apps-2.15.0}/idf_build_apps/manifest/manifest.py +20 -6
  26. {idf_build_apps-2.13.3 → idf_build_apps-2.15.0}/idf_build_apps/manifest/soc_header.py +1 -1
  27. {idf_build_apps-2.13.3 → idf_build_apps-2.15.0}/idf_build_apps/session_args.py +1 -1
  28. {idf_build_apps-2.13.3 → idf_build_apps-2.15.0}/idf_build_apps/utils.py +1 -1
  29. {idf_build_apps-2.13.3 → idf_build_apps-2.15.0}/idf_build_apps/yaml/__init__.py +1 -1
  30. {idf_build_apps-2.13.3 → idf_build_apps-2.15.0}/idf_build_apps/yaml/parser.py +39 -4
  31. {idf_build_apps-2.13.3 → idf_build_apps-2.15.0}/pyproject.toml +2 -2
  32. {idf_build_apps-2.13.3 → idf_build_apps-2.15.0}/setup.py +1 -1
  33. {idf_build_apps-2.13.3 → idf_build_apps-2.15.0}/tests/conftest.py +1 -1
  34. {idf_build_apps-2.13.3 → idf_build_apps-2.15.0}/tests/test_app.py +1 -1
  35. {idf_build_apps-2.13.3 → idf_build_apps-2.15.0}/tests/test_args.py +15 -1
  36. {idf_build_apps-2.13.3 → idf_build_apps-2.15.0}/tests/test_build.py +1 -2
  37. {idf_build_apps-2.13.3 → idf_build_apps-2.15.0}/tests/test_cmd.py +67 -1
  38. {idf_build_apps-2.13.3 → idf_build_apps-2.15.0}/tests/test_disable_reasons.py +1 -1
  39. {idf_build_apps-2.13.3 → idf_build_apps-2.15.0}/tests/test_finder.py +5 -5
  40. {idf_build_apps-2.13.3 → idf_build_apps-2.15.0}/tests/test_manifest.py +65 -14
  41. {idf_build_apps-2.13.3 → idf_build_apps-2.15.0}/tests/test_utils.py +1 -1
  42. {idf_build_apps-2.13.3 → idf_build_apps-2.15.0}/.editorconfig +0 -0
  43. {idf_build_apps-2.13.3 → idf_build_apps-2.15.0}/.git-blame-ignore-revs +0 -0
  44. {idf_build_apps-2.13.3 → idf_build_apps-2.15.0}/.gitattributes +0 -0
  45. {idf_build_apps-2.13.3 → idf_build_apps-2.15.0}/.github/dependabot.yml +0 -0
  46. {idf_build_apps-2.13.3 → idf_build_apps-2.15.0}/.gitignore +0 -0
  47. {idf_build_apps-2.13.3 → idf_build_apps-2.15.0}/.readthedocs.yml +0 -0
  48. {idf_build_apps-2.13.3 → idf_build_apps-2.15.0}/CONTRIBUTING.md +0 -0
  49. {idf_build_apps-2.13.3 → idf_build_apps-2.15.0}/LICENSE +0 -0
  50. {idf_build_apps-2.13.3 → idf_build_apps-2.15.0}/README.md +0 -0
  51. {idf_build_apps-2.13.3 → idf_build_apps-2.15.0}/docs/_apidoc_templates/module.rst_t +0 -0
  52. {idf_build_apps-2.13.3 → idf_build_apps-2.15.0}/docs/_apidoc_templates/package.rst_t +0 -0
  53. {idf_build_apps-2.13.3 → idf_build_apps-2.15.0}/docs/_apidoc_templates/toc.rst_t +0 -0
  54. {idf_build_apps-2.13.3 → idf_build_apps-2.15.0}/docs/_static/espressif-logo.svg +0 -0
  55. {idf_build_apps-2.13.3 → idf_build_apps-2.15.0}/docs/_static/theme_overrides.css +0 -0
  56. {idf_build_apps-2.13.3 → idf_build_apps-2.15.0}/docs/_templates/layout.html +0 -0
  57. {idf_build_apps-2.13.3 → idf_build_apps-2.15.0}/docs/en/Makefile +0 -0
  58. {idf_build_apps-2.13.3 → idf_build_apps-2.15.0}/docs/en/explanations/build.rst +0 -0
  59. {idf_build_apps-2.13.3 → idf_build_apps-2.15.0}/docs/en/explanations/build_status.rst +0 -0
  60. {idf_build_apps-2.13.3 → idf_build_apps-2.15.0}/docs/en/explanations/config_rules.rst +0 -0
  61. {idf_build_apps-2.13.3 → idf_build_apps-2.15.0}/docs/en/explanations/find.rst +0 -0
  62. {idf_build_apps-2.13.3 → idf_build_apps-2.15.0}/docs/en/guides/1.x_to_2.x.md +0 -0
  63. {idf_build_apps-2.13.3 → idf_build_apps-2.15.0}/docs/en/guides/custom_app.md +0 -0
  64. {idf_build_apps-2.13.3 → idf_build_apps-2.15.0}/docs/en/index.rst +0 -0
  65. {idf_build_apps-2.13.3 → idf_build_apps-2.15.0}/docs/en/others/CHANGELOG.md +0 -0
  66. {idf_build_apps-2.13.3 → idf_build_apps-2.15.0}/docs/en/others/CONTRIBUTING.md +0 -0
  67. {idf_build_apps-2.13.3 → idf_build_apps-2.15.0}/docs/en/references/cli.rst +0 -0
  68. {idf_build_apps-2.13.3 → idf_build_apps-2.15.0}/docs/en/references/config_file.rst +0 -0
  69. {idf_build_apps-2.13.3 → idf_build_apps-2.15.0}/idf_build_apps/py.typed +0 -0
  70. {idf_build_apps-2.13.3 → idf_build_apps-2.15.0}/idf_build_apps/vendors/__init__.py +0 -0
  71. {idf_build_apps-2.13.3 → idf_build_apps-2.15.0}/idf_build_apps/vendors/pydantic_sources.py +0 -0
  72. {idf_build_apps-2.13.3 → idf_build_apps-2.15.0}/license_header.txt +0 -0
@@ -9,7 +9,7 @@ jobs:
9
9
  deploy:
10
10
  runs-on: ubuntu-22.04
11
11
  steps:
12
- - uses: actions/checkout@v5
12
+ - uses: actions/checkout@v6
13
13
  - uses: actions/setup-python@v6
14
14
  with:
15
15
  python-version: "3.7"
@@ -46,7 +46,7 @@ jobs:
46
46
  pull-requests: write
47
47
  steps:
48
48
  - name: Check out
49
- uses: actions/checkout@v5
49
+ uses: actions/checkout@v6
50
50
 
51
51
  - name: Run synchronization to Jira
52
52
  uses: espressif/sync-jira-actions@v1
@@ -55,7 +55,7 @@ jobs:
55
55
  env:
56
56
  GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
57
57
  JIRA_PASS: ${{ secrets.JIRA_PASS }}
58
- JIRA_PROJECT: RDT
58
+ JIRA_PROJECT: CII
59
59
  JIRA_COMPONENT: idf-build-apps
60
60
  JIRA_URL: ${{ secrets.JIRA_URL }}
61
61
  JIRA_USER: ${{ secrets.JIRA_USER }}
@@ -7,7 +7,7 @@ jobs:
7
7
  build-docs:
8
8
  runs-on: ubuntu-22.04
9
9
  steps:
10
- - uses: actions/checkout@v5
10
+ - uses: actions/checkout@v6
11
11
  - name: Set up Python
12
12
  uses: actions/setup-python@v6
13
13
  with:
@@ -1,5 +1,9 @@
1
1
  name: Test Build IDF Apps
2
2
 
3
+ concurrency:
4
+ group: ${{ github.workflow }}-${{ github.ref }}-${{ github.run_id }}
5
+ cancel-in-progress: false
6
+
3
7
  on:
4
8
  pull_request:
5
9
  paths:
@@ -20,7 +24,7 @@ jobs:
20
24
  build-python-packages:
21
25
  runs-on: ubuntu-22.04
22
26
  steps:
23
- - uses: actions/checkout@v5
27
+ - uses: actions/checkout@v6
24
28
  - uses: actions/setup-python@v6
25
29
  with:
26
30
  python-version: '3.7'
@@ -29,7 +33,7 @@ jobs:
29
33
  pip install flit
30
34
  flit build
31
35
  - name: Upload built python packages
32
- uses: actions/upload-artifact@v4
36
+ uses: actions/upload-artifact@v6
33
37
  with:
34
38
  name: wheel
35
39
  path: dist/idf_build_apps-*.whl
@@ -39,13 +43,13 @@ jobs:
39
43
  needs: build-python-packages
40
44
  strategy:
41
45
  matrix:
42
- idf-branch: [ release-v5.0, release-v5.1, release-v5.2, release-v5.3 ]
46
+ idf-branch: [ release-v5.1, release-v5.2, release-v5.3, release-v5.4, release-v5.5 ]
43
47
  runs-on: ubuntu-latest
44
48
  container:
45
49
  image: espressif/idf:${{ matrix.idf-branch }}
46
50
  steps:
47
51
  - name: Download wheel
48
- uses: actions/download-artifact@v5
52
+ uses: actions/download-artifact@v7
49
53
  with:
50
54
  name: wheel
51
55
  - name: Build the Apps
@@ -67,7 +71,7 @@ jobs:
67
71
  env:
68
72
  FLIT_ROOT_INSTALL: 1
69
73
  steps:
70
- - uses: actions/checkout@v5
74
+ - uses: actions/checkout@v6
71
75
  - name: Build the Apps
72
76
  run: |
73
77
  bash $IDF_PATH/install.sh
@@ -97,7 +101,7 @@ jobs:
97
101
  branch:
98
102
  - release/v3.4
99
103
  steps:
100
- - uses: actions/checkout@v5
104
+ - uses: actions/checkout@v6
101
105
  - name: Install dependencies
102
106
  run: |
103
107
  apt update \
@@ -17,13 +17,13 @@ repos:
17
17
  - --use-current-year
18
18
  exclude: 'idf_build_apps/vendors/'
19
19
  - repo: https://github.com/astral-sh/ruff-pre-commit
20
- rev: 'v0.13.0'
20
+ rev: 'v0.14.11'
21
21
  hooks:
22
- - id: ruff
22
+ - id: ruff-check
23
23
  args: ['--fix']
24
24
  - id: ruff-format
25
25
  - repo: https://github.com/pre-commit/mirrors-mypy
26
- rev: 'v1.18.1'
26
+ rev: 'v1.19.1'
27
27
  hooks:
28
28
  - id: mypy
29
29
  args: ['--warn-unused-ignores']
@@ -1,9 +1,59 @@
1
- # Changelog
1
+ <a href="https://www.espressif.com">
2
+ <img src="https://www.espressif.com/sites/all/themes/espressif/logo-black.svg" align="right" height="20" />
3
+ </a>
4
+
5
+ # CHANGELOG
6
+
7
+ > All notable changes to this project are documented in this file.
8
+ > This list is not exhaustive - only important changes, fixes, and new features in the code are reflected here.
9
+
10
+ <div style="text-align: center;">
11
+ <a href="https://keepachangelog.com/en/1.1.0/">
12
+ <img alt="Static Badge" src="https://img.shields.io/badge/Keep%20a%20Changelog-v1.1.0-salmon?logo=keepachangelog&logoColor=black&labelColor=white&link=https%3A%2F%2Fkeepachangelog.com%2Fen%2F1.1.0%2F">
13
+ </a>
14
+ <a href="https://www.conventionalcommits.org/en/v1.0.0/">
15
+ <img alt="Static Badge" src="https://img.shields.io/badge/Conventional%20Commits-v1.0.0-pink?logo=conventionalcommits&logoColor=black&labelColor=white&link=https%3A%2F%2Fwww.conventionalcommits.org%2Fen%2Fv1.0.0%2F">
16
+ </a>
17
+ <a href="https://semver.org/spec/v2.0.0.html">
18
+ <img alt="Static Badge" src="https://img.shields.io/badge/Semantic%20Versioning-v2.0.0-grey?logo=semanticrelease&logoColor=black&labelColor=white&link=https%3A%2F%2Fsemver.org%2Fspec%2Fv2.0.0.html">
19
+ </a>
20
+ </div>
21
+ <hr>
22
+
23
+ ## v2.15.0 (2026-01-26)
2
24
 
3
- All notable changes to this project will be documented in this file.
25
+ ### New Features
26
+
27
+ - support detection of ESP-IDF build system v2 projects *(Sudeep Mohanty - 16479c0)*
28
+
29
+ ### 🐛 Bug Fixes
30
+
31
+ - mock common_components when it is none *(igor.udot - 273e603)*
32
+
33
+ ---
34
+
35
+ ## v2.14.0 (2026-01-16)
36
+
37
+ ### ✨ New Features
38
+
39
+ - support root_components placeholder *(igor.udot - 104959e)*
40
+
41
+ ### 🐛 Bug Fixes
42
+
43
+ - **pre-commit**: change mypy python_version from 3.9 to 3.10 *(Evgeny Torbin - bdf0788)*
44
+ - fixed issue that parser_bool_expr thorws AttributeError not caught *(Xiao Xufeng - 3878948)*
45
+ - `model_validate` does not support `extra` in python<=3.8 *(Fu Hanxi - 8a108a1)*
46
+ - add disabled apps to junit with `--include-all-apps` flag *(Evgeny Torbin - 071d4e3)*
47
+
48
+ ### 📖 Documentation
49
+
50
+ - base_components placeholder *(igor.udot - 7958201)*
51
+
52
+ ---
4
53
 
5
54
  ## v2.13.3 (2025-10-23)
6
55
 
56
+ ---
7
57
 
8
58
  ## v2.13.2 (2025-10-23)
9
59
 
@@ -12,6 +62,7 @@ All notable changes to this project will be documented in this file.
12
62
  - update broken tests for `size.json` *(Evgeny Torbin - c603221)*
13
63
  - change `idf_size.py --format json` to `--format json2` *(Evgeny Torbin - 49b9f3d)*
14
64
 
65
+ ---
15
66
 
16
67
  ## v2.13.1 (2025-09-29)
17
68
 
@@ -19,6 +70,7 @@ All notable changes to this project will be documented in this file.
19
70
 
20
71
  - path checking for modified apps *(Fu Hanxi - 18f554c)*
21
72
 
73
+ ---
22
74
 
23
75
  ## v2.13.0 (2025-09-26)
24
76
 
@@ -31,6 +83,7 @@ All notable changes to this project will be documented in this file.
31
83
  - **find_apps**: ignore target-specific sdkconfig files even without setting CONFIG_IDF_TARGET *(Fu Hanxi - 1861a7a)*
32
84
  - record `checked_should_build` *(Fu Hanxi - f37fff1)*
33
85
 
86
+ ---
34
87
 
35
88
  ## v2.12.3 (2025-09-16)
36
89
 
@@ -591,3 +644,15 @@ This is the last version to support ESP-IDF v4.1 since it's EOL on Feb. 24th, 20
591
644
  ### Added
592
645
 
593
646
  - Use `--format json` instead of `--json` with `idf_size.py`
647
+
648
+ ---
649
+
650
+ <div style="text-align: center;">
651
+ <small>
652
+ <b>
653
+ <a href="https://www.github.com/espressif/cz-plugin-espressif">Commitizen Espressif plugin</a>
654
+ </b>
655
+ <br>
656
+ <sup><a href="https://www.espressif.com">Espressif Systems CO LTD. (2026)</a><sup>
657
+ </small>
658
+ </div>
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: idf-build-apps
3
- Version: 2.13.3
3
+ Version: 2.15.0
4
4
  Summary: Tools for building ESP-IDF related apps.
5
5
  Author-email: Fu Hanxi <fuhanxi@espressif.com>
6
6
  Requires-Python: >=3.7
@@ -1,4 +1,4 @@
1
- # SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
1
+ # SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD
2
2
  # SPDX-License-Identifier: Apache-2.0
3
3
 
4
4
  import os
@@ -1,4 +1,4 @@
1
- # SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
1
+ # SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD
2
2
  # SPDX-License-Identifier: Apache-2.0
3
3
 
4
4
  import os
@@ -63,6 +63,17 @@ Here is an example of a manifest file:
63
63
  depends_filepatterns:
64
64
  - "common_header_files/**/*"
65
65
 
66
+ You may also reuse a common set of component dependencies by using the special placeholder ``- *common_components`` inside ``depends_components``. This placeholder is expanded when loading the manifest file, using the values provided via the CLI option ``--common-components`` (or the ``common_components`` argument to :meth:`~idf_build_apps.manifest.manifest.Manifest.from_file`).
67
+
68
+ .. code:: yaml
69
+
70
+ # rules.yml
71
+ examples/foo:
72
+ depends_components:
73
+ - *common_components
74
+ - "some_1"
75
+ - "some_2"
76
+
66
77
  The apps under folder ``examples/foo`` will be built with the following CLI options:
67
78
 
68
79
  - ``--manifest-files rules.yml --modified-files examples/foo/main/foo.c``
@@ -209,6 +209,15 @@ Reuse Lists
209
209
 
210
210
  To reuse the items defined in a list, you can use the ``+`` and ``-`` postfixes respectively. The order of calculation is always ``+`` first, followed by ``-``.
211
211
 
212
+ Placeholder: ``*common_components``
213
+ -----------------------------------
214
+
215
+ In addition to YAML anchors, ``idf-build-apps`` also supports a special placeholder entry ``- *common_components`` inside ``depends_components``.
216
+
217
+ When loading the manifest file, this placeholder is expanded using the values provided via the CLI option ``--common-components`` (or the ``common_components`` argument to :meth:`~idf_build_apps.manifest.manifest.Manifest.from_file`).
218
+
219
+ This placeholder entry is only supported inside ``depends_components``.
220
+
212
221
  Array Elements as Strings
213
222
  -------------------------
214
223
 
@@ -1,4 +1,4 @@
1
- # SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
1
+ # SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD
2
2
  # SPDX-License-Identifier: Apache-2.0
3
3
 
4
4
  """
@@ -8,7 +8,7 @@ Tools for building ESP-IDF related apps.
8
8
  # ruff: noqa: E402
9
9
  # avoid circular imports
10
10
 
11
- __version__ = '2.13.3'
11
+ __version__ = '2.15.0'
12
12
 
13
13
  from .session_args import (
14
14
  SessionArgs,
@@ -1,4 +1,4 @@
1
- # SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
1
+ # SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD
2
2
  # SPDX-License-Identifier: Apache-2.0
3
3
 
4
4
  from .main import (
@@ -1,4 +1,4 @@
1
- # SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
1
+ # SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD
2
2
  # SPDX-License-Identifier: Apache-2.0
3
3
 
4
4
  import copy
@@ -511,7 +511,9 @@ class App(BaseModel):
511
511
  BuildStatus.UNKNOWN,
512
512
  BuildStatus.SHOULD_BE_BUILT,
513
513
  ):
514
- self.build_comment = f'Build {self.build_status.value}. Skipping...'
514
+ if not self.build_comment:
515
+ self.build_comment = f'Build {self.build_status.value}. Skipping...'
516
+
515
517
  return
516
518
 
517
519
  # real build starts here
@@ -954,7 +956,11 @@ class CMakeApp(App):
954
956
 
955
957
  # While ESP-IDF component CMakeLists files can be identified by the presence of 'idf_component_register' string,
956
958
  # there is no equivalent for the project CMakeLists files. This seems to be the best option...
957
- CMAKE_PROJECT_LINE: t.ClassVar[str] = r'include($ENV{IDF_PATH}/tools/cmake/project.cmake)'
959
+ # Support both build system v1 and v2 patterns
960
+ CMAKE_PROJECT_LINE: t.ClassVar[t.List[str]] = [
961
+ r'include($ENV{IDF_PATH}/tools/cmake/project.cmake)',
962
+ r'include($ENV{IDF_PATH}/tools/cmakev2/idf.cmake)',
963
+ ]
958
964
 
959
965
  build_system: Literal['cmake'] = 'cmake' # type: ignore
960
966
 
@@ -1062,10 +1068,12 @@ class CMakeApp(App):
1062
1068
  if not cmakelists_file_content:
1063
1069
  return False
1064
1070
 
1065
- if cls.CMAKE_PROJECT_LINE not in cmakelists_file_content:
1066
- return False
1071
+ # Check if any of the supported build system patterns are present
1072
+ for pattern in cls.CMAKE_PROJECT_LINE:
1073
+ if pattern in cmakelists_file_content:
1074
+ return True
1067
1075
 
1068
- return True
1076
+ return False
1069
1077
 
1070
1078
 
1071
1079
  class AppDeserializer(BaseModel):
@@ -1,4 +1,4 @@
1
- # SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
1
+ # SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD
2
2
  # SPDX-License-Identifier: Apache-2.0
3
3
 
4
4
  import argparse
@@ -302,6 +302,19 @@ class DependencyDrivenBuildArguments(GlobalArguments):
302
302
  ),
303
303
  default=None, # type: ignore
304
304
  )
305
+ common_components: t.Optional[t.List[str]] = field(
306
+ FieldMetadata(
307
+ validate_method=[ValidateMethod.TO_LIST],
308
+ type=semicolon_separated_str_to_list,
309
+ shorthand='-rc',
310
+ ),
311
+ description='semicolon-separated list of components. '
312
+ 'expand the `- *common_components` placeholder in manifests. '
313
+ 'Must be specified together with --modified-components. '
314
+ 'If set to "", the value would be considered as None. '
315
+ 'If set to ";", the value would be considered as an empty list.',
316
+ default=None, # type: ignore
317
+ )
305
318
  deactivate_dependency_driven_build_by_filepatterns: t.Optional[t.List[str]] = field(
306
319
  FieldMetadata(
307
320
  validate_method=[ValidateMethod.TO_LIST],
@@ -374,6 +387,7 @@ class DependencyDrivenBuildArguments(GlobalArguments):
374
387
  App.MANIFEST = Manifest.from_files(
375
388
  self.manifest_files,
376
389
  root_path=to_absolute_path(self.manifest_rootpath),
390
+ common_components=self.common_components,
377
391
  )
378
392
 
379
393
  @property
@@ -1,4 +1,4 @@
1
- # SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
1
+ # SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD
2
2
  # SPDX-License-Identifier: Apache-2.0
3
3
 
4
4
  import os
@@ -1,4 +1,4 @@
1
- # SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
1
+ # SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD
2
2
  # SPDX-License-Identifier: Apache-2.0
3
3
 
4
4
  import enum
@@ -1,4 +1,4 @@
1
- # SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
1
+ # SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD
2
2
  # SPDX-License-Identifier: Apache-2.0
3
3
 
4
4
  import logging
@@ -1,4 +1,4 @@
1
- # SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
1
+ # SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD
2
2
  # SPDX-License-Identifier: Apache-2.0
3
3
 
4
4
  from .report import (
@@ -1,4 +1,4 @@
1
- # SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
1
+ # SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD
2
2
  # SPDX-License-Identifier: Apache-2.0
3
3
 
4
4
  """
@@ -1,4 +1,4 @@
1
- # SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
1
+ # SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD
2
2
  # SPDX-License-Identifier: Apache-2.0
3
3
 
4
4
  import os
@@ -1,4 +1,4 @@
1
- # SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
1
+ # SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD
2
2
  # SPDX-License-Identifier: Apache-2.0
3
3
 
4
4
  import logging
@@ -1,6 +1,6 @@
1
1
  # PYTHON_ARGCOMPLETE_OK
2
2
 
3
- # SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
3
+ # SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD
4
4
  # SPDX-License-Identifier: Apache-2.0
5
5
 
6
6
  import argparse
@@ -386,23 +386,26 @@ def main():
386
386
  sys.exit(0)
387
387
 
388
388
  kwargs = vars(args)
389
+ kwargs_without_none = drop_none_kwargs(kwargs)
389
390
  action = kwargs.pop('action')
390
391
  config_file = kwargs.pop('config_file')
391
392
  if config_file:
392
393
  apply_config_file(config_file)
393
394
 
394
395
  if action == 'dump-manifest-sha':
395
- arguments = DumpManifestShaArguments(**drop_none_kwargs(kwargs))
396
+ arguments = DumpManifestShaArguments(**kwargs_without_none)
396
397
  Manifest.from_files(arguments.manifest_files).dump_sha_values(arguments.output)
397
398
  sys.exit(0)
398
- elif action == 'find':
399
- arguments = FindArguments(**drop_none_kwargs(kwargs))
399
+
400
+ if action == 'find':
401
+ arguments = FindArguments(**kwargs_without_none)
400
402
  else:
401
- arguments = BuildArguments(**drop_none_kwargs(kwargs))
403
+ arguments = BuildArguments(**kwargs_without_none)
402
404
 
403
405
  # real call starts here
404
406
  # build also needs to find first
405
- apps = find_apps(args.paths, args.target, find_arguments=arguments)
407
+ apps = find_apps(args.paths, args.target, find_arguments=FindArguments.model_validate(kwargs_without_none))
408
+
406
409
  if isinstance(arguments, FindArguments): # find only
407
410
  if arguments.output:
408
411
  os.makedirs(os.path.dirname(os.path.realpath(arguments.output)), exist_ok=True)
@@ -444,6 +447,12 @@ def main():
444
447
  for app in failed_apps:
445
448
  print(f' {app}')
446
449
 
450
+ disabled_apps = [app for app in apps if app.build_status == BuildStatus.DISABLED]
451
+ if disabled_apps:
452
+ print('Disabled the following apps:')
453
+ for app in disabled_apps:
454
+ print(f' {app}')
455
+
447
456
  if ret_code != 0:
448
457
  sys.exit(ret_code)
449
458
 
@@ -1,4 +1,4 @@
1
- # SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
1
+ # SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD
2
2
  # SPDX-License-Identifier: Apache-2.0
3
3
 
4
4
  """
@@ -1,4 +1,4 @@
1
- # SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
1
+ # SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD
2
2
  # SPDX-License-Identifier: Apache-2.0
3
3
  import contextvars
4
4
  import logging
@@ -45,7 +45,7 @@ class IfClause:
45
45
  try:
46
46
  self.stmt: BoolStmt = parse_bool_expr(stmt)
47
47
  self._stmt: str = stmt
48
- except (ParseException, InvalidIfClause) as ex:
48
+ except (ParseException, InvalidIfClause, AttributeError) as ex:
49
49
  raise InvalidIfClause(f'Invalid if clause: {stmt}. {ex}')
50
50
 
51
51
  self.temporary = temporary
@@ -342,12 +342,19 @@ class Manifest:
342
342
  self._rule_paths = {rule.folder: rule for rule in self.rules}
343
343
 
344
344
  @classmethod
345
- def from_files(cls, paths: t.Iterable[PathLike], *, root_path: str = os.curdir) -> 'Manifest':
345
+ def from_files(
346
+ cls,
347
+ paths: t.Iterable[PathLike],
348
+ *,
349
+ root_path: str = os.curdir,
350
+ common_components: t.Optional[t.Sequence[str]] = None,
351
+ ) -> 'Manifest':
346
352
  """
347
353
  Create a Manifest instance from multiple manifest files
348
354
 
349
355
  :param paths: manifest file paths
350
356
  :param root_path: root path for relative paths in manifest files
357
+ :param common_components: sequence of strings to expand the ``- *common_components`` placeholder in manifests
351
358
  :return: Manifest instance
352
359
  """
353
360
  # folder, defined as dict
@@ -356,7 +363,7 @@ class Manifest:
356
363
  rules: t.List[FolderRule] = []
357
364
  for path in paths:
358
365
  LOGGER.debug('Loading manifest file %s', path)
359
- _manifest = cls.from_file(path, root_path=root_path)
366
+ _manifest = cls.from_file(path, root_path=root_path, common_components=common_components)
360
367
 
361
368
  for rule in _manifest.rules:
362
369
  if rule.folder in _known_folders:
@@ -373,15 +380,22 @@ class Manifest:
373
380
  return Manifest(rules, root_path=root_path)
374
381
 
375
382
  @classmethod
376
- def from_file(cls, path: PathLike, *, root_path: str = os.curdir) -> 'Manifest':
383
+ def from_file(
384
+ cls,
385
+ path: PathLike,
386
+ *,
387
+ root_path: str = os.curdir,
388
+ common_components: t.Optional[t.Sequence[str]] = None,
389
+ ) -> 'Manifest':
377
390
  """
378
391
  Create a Manifest instance from a manifest file
379
392
 
380
393
  :param path: path to the manifest file
381
394
  :param root_path: root path for relative paths in manifest file
395
+ :param common_components: sequence of strings to expand the ``{{root_components}}`` placeholder in manifests
382
396
  :return: Manifest instance
383
397
  """
384
- manifest_dict = parse(path)
398
+ manifest_dict = parse(path, common_components=common_components)
385
399
 
386
400
  rules: t.List[FolderRule] = []
387
401
  for folder, folder_rule in manifest_dict.items():
@@ -1,4 +1,4 @@
1
- # SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
1
+ # SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD
2
2
  # SPDX-License-Identifier: Apache-2.0
3
3
 
4
4
  import esp_bool_parser
@@ -1,4 +1,4 @@
1
- # SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
1
+ # SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD
2
2
  # SPDX-License-Identifier: Apache-2.0
3
3
 
4
4
  import logging
@@ -1,4 +1,4 @@
1
- # SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
1
+ # SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD
2
2
  # SPDX-License-Identifier: Apache-2.0
3
3
 
4
4
  import fnmatch
@@ -1,4 +1,4 @@
1
- # SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
1
+ # SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD
2
2
  # SPDX-License-Identifier: Apache-2.0
3
3
 
4
4
  from .parser import (
@@ -1,4 +1,4 @@
1
- # SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
1
+ # SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD
2
2
  # SPDX-License-Identifier: Apache-2.0
3
3
 
4
4
  import typing as t
@@ -62,8 +62,43 @@ def parse_postfixes(manifest_dict: t.Dict):
62
62
  manifest_dict[folder] = updated_folder
63
63
 
64
64
 
65
- def parse(path: PathLike) -> t.Dict:
66
- with open(path) as f:
67
- manifest_dict = yaml.safe_load(f) or {}
65
+ def flatten_common_components(manifest_dict: t.Dict):
66
+ """
67
+ Flattens nested lists under `depends_components` into a single list of strings.
68
+ """
69
+
70
+ for folder, folder_rule in manifest_dict.items():
71
+ if not isinstance(folder_rule, t.Dict):
72
+ continue
73
+
74
+ depends = folder_rule.get('depends_components')
75
+ if not isinstance(depends, t.List):
76
+ continue
77
+
78
+ flattened: t.List[str] = []
79
+ for item in depends:
80
+ if not item:
81
+ continue
82
+ if isinstance(item, t.List):
83
+ flattened.extend(map(str, item))
84
+ else:
85
+ flattened.append(item)
86
+
87
+ folder_rule['depends_components'] = flattened
88
+
89
+
90
+ def parse(path: PathLike, *, common_components: t.Optional[t.Sequence[str]] = None) -> t.Dict:
91
+ common_components_yaml = (
92
+ '.common_components: &common_components\n' + '\n'.join(f' - {component}' for component in common_components)
93
+ if common_components
94
+ else '.common_components: &common_components\n null'
95
+ )
96
+
97
+ with open(path, encoding='utf-8') as f:
98
+ user_yaml = f.read()
99
+
100
+ manifest_dict = yaml.safe_load(f'{common_components_yaml}\n{user_yaml}') or {}
101
+
102
+ flatten_common_components(manifest_dict)
68
103
  parse_postfixes(manifest_dict)
69
104
  return manifest_dict
@@ -65,7 +65,7 @@ idf-build-apps = "idf_build_apps:main.main"
65
65
 
66
66
  [tool.commitizen]
67
67
  name = "czespressif"
68
- version = "2.13.3"
68
+ version = "2.15.0"
69
69
 
70
70
  tag_format = "v$version"
71
71
  version_scheme = "pep440"
@@ -172,4 +172,4 @@ docstring-code-format = true
172
172
  ignore-variadic-names = true
173
173
 
174
174
  [tool.mypy]
175
- python_version = "3.9"
175
+ python_version = "3.10"
@@ -38,7 +38,7 @@ entry_points = \
38
38
  {'console_scripts': ['idf-build-apps = idf_build_apps:main.main']}
39
39
 
40
40
  setup(name='idf-build-apps',
41
- version='2.13.3',
41
+ version='2.15.0',
42
42
  description='Tools for building ESP-IDF related apps.',
43
43
  author=None,
44
44
  author_email='Fu Hanxi <fuhanxi@espressif.com>',
@@ -1,4 +1,4 @@
1
- # SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
1
+ # SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD
2
2
  # SPDX-License-Identifier: Apache-2.0
3
3
  import os
4
4
 
@@ -1,4 +1,4 @@
1
- # SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
1
+ # SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD
2
2
  # SPDX-License-Identifier: Apache-2.0
3
3
  import os
4
4
 
@@ -1,4 +1,4 @@
1
- # SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
1
+ # SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD
2
2
  # SPDX-License-Identifier: Apache-2.0
3
3
  import os
4
4
  from tempfile import NamedTemporaryFile
@@ -170,6 +170,20 @@ modified_files = [
170
170
  assert args.deactivate_dependency_driven_build_by_components == ['baz']
171
171
 
172
172
 
173
+ def test_func_common_components():
174
+ with open(IDF_BUILD_APPS_TOML_FN, 'w') as fw:
175
+ fw.write("""
176
+ common_components = [
177
+ 'hello',
178
+ 'world'
179
+ ]
180
+ """)
181
+
182
+ args = FindArguments()
183
+
184
+ assert args.common_components == ['hello', 'world']
185
+
186
+
173
187
  def test_combination_validation():
174
188
  """Test that target options can now be combined"""
175
189
  # Mock targets for consistent testing
@@ -1,4 +1,4 @@
1
- # SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
1
+ # SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD
2
2
  # SPDX-License-Identifier: Apache-2.0
3
3
 
4
4
  import json
@@ -253,7 +253,6 @@ class TestBuild:
253
253
 
254
254
  expected_files = [
255
255
  'libesp_timer.a:system_time.c.obj',
256
- 'libc.a:libc_a-vfprintf.o',
257
256
  'libfreertos.a:tasks.c.obj',
258
257
  'libheap.a:tlsf.c.obj',
259
258
  ]
@@ -1,11 +1,15 @@
1
- # SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
1
+ # SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD
2
2
  # SPDX-License-Identifier: Apache-2.0
3
3
  import os
4
4
  import sys
5
5
  from pathlib import Path
6
+ from textwrap import dedent
7
+ from xml.etree import ElementTree
6
8
 
7
9
  import pytest
10
+ from conftest import create_project
8
11
 
12
+ from idf_build_apps.constants import SUPPORTED_TARGETS
9
13
  from idf_build_apps.main import main
10
14
  from idf_build_apps.utils import InvalidCommand
11
15
 
@@ -95,3 +99,65 @@ bar:
95
99
  assert f'Loading manifest file {os.path.join(tmp_path, "manifest.yml")}' in err
96
100
  assert f'"{os.path.join(tmp_path, "foo")}" does not exist' in err
97
101
  assert f'"{os.path.join(tmp_path, "bar")}" does not exist' in err
102
+
103
+
104
+ def test_build_include_all_apps(tmp_path, monkeypatch, capsys):
105
+ create_project('foo', tmp_path)
106
+
107
+ manifest = tmp_path / 'manifest.yml'
108
+ manifest.write_text(
109
+ dedent("""\
110
+ foo:
111
+ disable:
112
+ - if: IDF_TARGET == "esp32"
113
+ """)
114
+ )
115
+
116
+ with monkeypatch.context() as m:
117
+ m.setattr(
118
+ sys,
119
+ 'argv',
120
+ [
121
+ 'idf-build-apps',
122
+ 'build',
123
+ '--paths',
124
+ 'foo',
125
+ '--manifest-files',
126
+ str(manifest),
127
+ '--check-manifest-rules',
128
+ '--include-all-apps',
129
+ '--junitxml',
130
+ str(tmp_path / 'junit.xml'),
131
+ '--dry-run',
132
+ ],
133
+ )
134
+ main()
135
+
136
+ out, err = capsys.readouterr()
137
+ assert err == ''
138
+ assert 'Disabled the following apps' in out
139
+ assert out.count('Disabled by manifest rule: IDF_TARGET == "esp32"') == 1
140
+
141
+ with open(str(tmp_path / 'junit.xml')) as f:
142
+ xml = ElementTree.fromstring(f.read())
143
+
144
+ test_suite = xml.findall('testsuite')[0]
145
+ assert test_suite.attrib['tests'] == '0'
146
+ assert test_suite.attrib['failures'] == '0'
147
+ assert test_suite.attrib['errors'] == '0'
148
+ assert test_suite.attrib['skipped'] == str(len(SUPPORTED_TARGETS))
149
+
150
+ disabled_testcases = 0
151
+
152
+ for case in test_suite.findall('testcase'):
153
+ if case.get('name') != 'foo/build':
154
+ continue
155
+
156
+ skipped = case.find('skipped')
157
+ if skipped is None:
158
+ continue
159
+
160
+ if skipped.get('message') == 'Disabled by manifest rule: IDF_TARGET == "esp32"':
161
+ disabled_testcases += 1
162
+
163
+ assert disabled_testcases == 1
@@ -1,4 +1,4 @@
1
- # SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
1
+ # SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD
2
2
  # SPDX-License-Identifier: Apache-2.0
3
3
 
4
4
 
@@ -1,4 +1,4 @@
1
- # SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
1
+ # SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD
2
2
  # SPDX-License-Identifier: Apache-2.0
3
3
 
4
4
  import os
@@ -118,9 +118,9 @@ examples/get-started:
118
118
  yaml_file = tmp_path / 'test.yml'
119
119
  yaml_file.write_text(
120
120
  f"""
121
- {test_dir}:
122
- enable:
123
- - if: IDF_TARGET == "esp32s2"
121
+ {test_dir}:
122
+ enable:
123
+ - if: IDF_TARGET == "esp32s2"
124
124
  """,
125
125
  encoding='utf8',
126
126
  )
@@ -138,7 +138,7 @@ examples/get-started:
138
138
  for app in apps:
139
139
  assert app.build_status == BuildStatus.DISABLED
140
140
  app.build()
141
- assert app.build_comment == 'Build disabled. Skipping...'
141
+ assert app.build_comment.startswith('Not enabled by manifest rules:')
142
142
 
143
143
 
144
144
  class TestFindWithModifiedFilesComponents:
@@ -1,4 +1,4 @@
1
- # SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
1
+ # SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD
2
2
  # SPDX-License-Identifier: Apache-2.0
3
3
  import os
4
4
 
@@ -176,6 +176,57 @@ test5:
176
176
  assert manifest.depends_components('test5', 'esp32', '123123') == ['some_1', 'some_2', 'some_3']
177
177
  assert manifest.depends_components('test5', None, None) == ['some_1', 'some_2', 'some_3']
178
178
 
179
+ def test_manifest_common_components(self, tmp_path):
180
+ common_components = ['hello', 'world', 123]
181
+
182
+ yaml_file = tmp_path / 'test.yml'
183
+ yaml_file.write_text(
184
+ """
185
+ test5:
186
+ depends_components:
187
+ - *common_components
188
+ - "some_1"
189
+ - "some_2"
190
+ - "some_3"
191
+
192
+ """,
193
+ encoding='utf8',
194
+ )
195
+
196
+ manifest = Manifest.from_file(yaml_file, common_components=common_components)
197
+ assert manifest.depends_components('test5', None, None) == [
198
+ 'hello',
199
+ 'world',
200
+ '123',
201
+ 'some_1',
202
+ 'some_2',
203
+ 'some_3',
204
+ ]
205
+
206
+ def test_manifest_empty_common_components(self, tmp_path):
207
+ common_components = None
208
+
209
+ yaml_file = tmp_path / 'test.yml'
210
+ yaml_file.write_text(
211
+ """
212
+ test5:
213
+ depends_components:
214
+ - *common_components
215
+ - "some_1"
216
+ - "some_2"
217
+ - "some_3"
218
+
219
+ """,
220
+ encoding='utf8',
221
+ )
222
+
223
+ manifest = Manifest.from_file(yaml_file, common_components=common_components)
224
+ assert manifest.depends_components('test5', None, None) == [
225
+ 'some_1',
226
+ 'some_2',
227
+ 'some_3',
228
+ ]
229
+
179
230
  def test_manifest_switch_clause_with_postfix(self, tmp_path):
180
231
  yaml_file = tmp_path / 'test.yml'
181
232
 
@@ -213,12 +264,12 @@ test1:
213
264
 
214
265
  yaml_file.write_text(
215
266
  """
216
- test1:
217
- depends_components:
218
- - if: IDF_VERSION == "5.9.0"
219
- content: [ "VVV" ]
220
- - default: ["some_1", "some_2", "some_3"]
221
- - hello: 123
267
+ test1:
268
+ depends_components:
269
+ - if: IDF_VERSION == "5.9.0"
270
+ content: [ "VVV" ]
271
+ - default: ["some_1", "some_2", "some_3"]
272
+ - hello: 123
222
273
 
223
274
  """,
224
275
  encoding='utf8',
@@ -231,13 +282,13 @@ test1:
231
282
 
232
283
  yaml_file.write_text(
233
284
  """
234
- test1:
235
- depends_components:
236
- - if: IDF_VERSION == "5.9.0"
237
- content: [ "VVV" ]
238
- - default: ["some_1", "some_2", "some_3"]
239
- - 123
240
- - 234
285
+ test1:
286
+ depends_components:
287
+ - if: IDF_VERSION == "5.9.0"
288
+ content: [ "VVV" ]
289
+ - default: ["some_1", "some_2", "some_3"]
290
+ - 123
291
+ - 234
241
292
  """,
242
293
  encoding='utf8',
243
294
  )
@@ -1,4 +1,4 @@
1
- # SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
1
+ # SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD
2
2
  # SPDX-License-Identifier: Apache-2.0
3
3
  import os
4
4
  from pathlib import (
File without changes