idf-build-apps 2.5.0rc0__tar.gz → 2.5.0rc1__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.5.0rc0 → idf_build_apps-2.5.0rc1}/CHANGELOG.md +10 -0
  2. {idf_build_apps-2.5.0rc0 → idf_build_apps-2.5.0rc1}/PKG-INFO +1 -1
  3. {idf_build_apps-2.5.0rc0 → idf_build_apps-2.5.0rc1}/docs/en/references/config_file.md +1 -1
  4. idf_build_apps-2.5.0rc1/docs/en/references/manifest.rst +281 -0
  5. {idf_build_apps-2.5.0rc0 → idf_build_apps-2.5.0rc1}/idf_build_apps/__init__.py +1 -1
  6. {idf_build_apps-2.5.0rc0 → idf_build_apps-2.5.0rc1}/idf_build_apps/app.py +0 -4
  7. {idf_build_apps-2.5.0rc0 → idf_build_apps-2.5.0rc1}/idf_build_apps/args.py +64 -7
  8. {idf_build_apps-2.5.0rc0 → idf_build_apps-2.5.0rc1}/idf_build_apps/main.py +0 -3
  9. {idf_build_apps-2.5.0rc0 → idf_build_apps-2.5.0rc1}/pyproject.toml +1 -1
  10. {idf_build_apps-2.5.0rc0 → idf_build_apps-2.5.0rc1}/setup.py +1 -1
  11. {idf_build_apps-2.5.0rc0 → idf_build_apps-2.5.0rc1}/tests/test_args.py +18 -2
  12. idf_build_apps-2.5.0rc0/docs/en/references/manifest.md +0 -245
  13. {idf_build_apps-2.5.0rc0 → idf_build_apps-2.5.0rc1}/.editorconfig +0 -0
  14. {idf_build_apps-2.5.0rc0 → idf_build_apps-2.5.0rc1}/.git-blame-ignore-revs +0 -0
  15. {idf_build_apps-2.5.0rc0 → idf_build_apps-2.5.0rc1}/.gitattributes +0 -0
  16. {idf_build_apps-2.5.0rc0 → idf_build_apps-2.5.0rc1}/.github/dependabot.yml +0 -0
  17. {idf_build_apps-2.5.0rc0 → idf_build_apps-2.5.0rc1}/.github/workflows/check-pre-commit.yml +0 -0
  18. {idf_build_apps-2.5.0rc0 → idf_build_apps-2.5.0rc1}/.github/workflows/issue_comment.yml +0 -0
  19. {idf_build_apps-2.5.0rc0 → idf_build_apps-2.5.0rc1}/.github/workflows/new_issues.yml +0 -0
  20. {idf_build_apps-2.5.0rc0 → idf_build_apps-2.5.0rc1}/.github/workflows/new_prs.yml +0 -0
  21. {idf_build_apps-2.5.0rc0 → idf_build_apps-2.5.0rc1}/.github/workflows/publish-pypi.yml +0 -0
  22. {idf_build_apps-2.5.0rc0 → idf_build_apps-2.5.0rc1}/.github/workflows/test-build-docs.yml +0 -0
  23. {idf_build_apps-2.5.0rc0 → idf_build_apps-2.5.0rc1}/.github/workflows/test-build-idf-apps.yml +0 -0
  24. {idf_build_apps-2.5.0rc0 → idf_build_apps-2.5.0rc1}/.gitignore +0 -0
  25. {idf_build_apps-2.5.0rc0 → idf_build_apps-2.5.0rc1}/.pre-commit-config.yaml +0 -0
  26. {idf_build_apps-2.5.0rc0 → idf_build_apps-2.5.0rc1}/.readthedocs.yml +0 -0
  27. {idf_build_apps-2.5.0rc0 → idf_build_apps-2.5.0rc1}/CONTRIBUTING.md +0 -0
  28. {idf_build_apps-2.5.0rc0 → idf_build_apps-2.5.0rc1}/LICENSE +0 -0
  29. {idf_build_apps-2.5.0rc0 → idf_build_apps-2.5.0rc1}/README.md +0 -0
  30. {idf_build_apps-2.5.0rc0 → idf_build_apps-2.5.0rc1}/docs/_apidoc_templates/module.rst_t +0 -0
  31. {idf_build_apps-2.5.0rc0 → idf_build_apps-2.5.0rc1}/docs/_apidoc_templates/package.rst_t +0 -0
  32. {idf_build_apps-2.5.0rc0 → idf_build_apps-2.5.0rc1}/docs/_apidoc_templates/toc.rst_t +0 -0
  33. {idf_build_apps-2.5.0rc0 → idf_build_apps-2.5.0rc1}/docs/_static/espressif-logo.svg +0 -0
  34. {idf_build_apps-2.5.0rc0 → idf_build_apps-2.5.0rc1}/docs/_static/theme_overrides.css +0 -0
  35. {idf_build_apps-2.5.0rc0 → idf_build_apps-2.5.0rc1}/docs/_templates/layout.html +0 -0
  36. {idf_build_apps-2.5.0rc0 → idf_build_apps-2.5.0rc1}/docs/conf_common.py +0 -0
  37. {idf_build_apps-2.5.0rc0 → idf_build_apps-2.5.0rc1}/docs/en/Makefile +0 -0
  38. {idf_build_apps-2.5.0rc0 → idf_build_apps-2.5.0rc1}/docs/en/conf.py +0 -0
  39. {idf_build_apps-2.5.0rc0 → idf_build_apps-2.5.0rc1}/docs/en/explanations/build.rst +0 -0
  40. {idf_build_apps-2.5.0rc0 → idf_build_apps-2.5.0rc1}/docs/en/explanations/config_rules.rst +0 -0
  41. {idf_build_apps-2.5.0rc0 → idf_build_apps-2.5.0rc1}/docs/en/explanations/dependency_driven_build.rst +0 -0
  42. {idf_build_apps-2.5.0rc0 → idf_build_apps-2.5.0rc1}/docs/en/explanations/find.rst +0 -0
  43. {idf_build_apps-2.5.0rc0 → idf_build_apps-2.5.0rc1}/docs/en/guides/1.x_to_2.x.md +0 -0
  44. {idf_build_apps-2.5.0rc0 → idf_build_apps-2.5.0rc1}/docs/en/index.rst +0 -0
  45. {idf_build_apps-2.5.0rc0 → idf_build_apps-2.5.0rc1}/docs/en/others/CHANGELOG.md +0 -0
  46. {idf_build_apps-2.5.0rc0 → idf_build_apps-2.5.0rc1}/docs/en/others/CONTRIBUTING.md +0 -0
  47. {idf_build_apps-2.5.0rc0 → idf_build_apps-2.5.0rc1}/docs/en/references/cli.rst +0 -0
  48. {idf_build_apps-2.5.0rc0 → idf_build_apps-2.5.0rc1}/idf_build_apps/__main__.py +0 -0
  49. {idf_build_apps-2.5.0rc0 → idf_build_apps-2.5.0rc1}/idf_build_apps/autocompletions.py +0 -0
  50. {idf_build_apps-2.5.0rc0 → idf_build_apps-2.5.0rc1}/idf_build_apps/config.py +0 -0
  51. {idf_build_apps-2.5.0rc0 → idf_build_apps-2.5.0rc1}/idf_build_apps/constants.py +0 -0
  52. {idf_build_apps-2.5.0rc0 → idf_build_apps-2.5.0rc1}/idf_build_apps/finder.py +0 -0
  53. {idf_build_apps-2.5.0rc0 → idf_build_apps-2.5.0rc1}/idf_build_apps/junit/__init__.py +0 -0
  54. {idf_build_apps-2.5.0rc0 → idf_build_apps-2.5.0rc1}/idf_build_apps/junit/report.py +0 -0
  55. {idf_build_apps-2.5.0rc0 → idf_build_apps-2.5.0rc1}/idf_build_apps/junit/utils.py +0 -0
  56. {idf_build_apps-2.5.0rc0 → idf_build_apps-2.5.0rc1}/idf_build_apps/log.py +0 -0
  57. {idf_build_apps-2.5.0rc0 → idf_build_apps-2.5.0rc1}/idf_build_apps/manifest/__init__.py +0 -0
  58. {idf_build_apps-2.5.0rc0 → idf_build_apps-2.5.0rc1}/idf_build_apps/manifest/if_parser.py +0 -0
  59. {idf_build_apps-2.5.0rc0 → idf_build_apps-2.5.0rc1}/idf_build_apps/manifest/manifest.py +0 -0
  60. {idf_build_apps-2.5.0rc0 → idf_build_apps-2.5.0rc1}/idf_build_apps/manifest/soc_header.py +0 -0
  61. {idf_build_apps-2.5.0rc0 → idf_build_apps-2.5.0rc1}/idf_build_apps/session_args.py +0 -0
  62. {idf_build_apps-2.5.0rc0 → idf_build_apps-2.5.0rc1}/idf_build_apps/utils.py +0 -0
  63. {idf_build_apps-2.5.0rc0 → idf_build_apps-2.5.0rc1}/idf_build_apps/yaml/__init__.py +0 -0
  64. {idf_build_apps-2.5.0rc0 → idf_build_apps-2.5.0rc1}/idf_build_apps/yaml/parser.py +0 -0
  65. {idf_build_apps-2.5.0rc0 → idf_build_apps-2.5.0rc1}/license_header.txt +0 -0
  66. {idf_build_apps-2.5.0rc0 → idf_build_apps-2.5.0rc1}/tests/conftest.py +0 -0
  67. {idf_build_apps-2.5.0rc0 → idf_build_apps-2.5.0rc1}/tests/test_app.py +0 -0
  68. {idf_build_apps-2.5.0rc0 → idf_build_apps-2.5.0rc1}/tests/test_build.py +0 -0
  69. {idf_build_apps-2.5.0rc0 → idf_build_apps-2.5.0rc1}/tests/test_cmd.py +0 -0
  70. {idf_build_apps-2.5.0rc0 → idf_build_apps-2.5.0rc1}/tests/test_finder.py +0 -0
  71. {idf_build_apps-2.5.0rc0 → idf_build_apps-2.5.0rc1}/tests/test_manifest.py +0 -0
  72. {idf_build_apps-2.5.0rc0 → idf_build_apps-2.5.0rc1}/tests/test_utils.py +0 -0
@@ -2,6 +2,16 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
+ ## v2.5.0rc1 (2024-09-17)
6
+
7
+ ### Fix
8
+
9
+ - build_arguments expand @p placeholders
10
+
11
+ ### Refactor
12
+
13
+ - rename BuildArguments.ignore_warning_strings to ignore_warning_strs
14
+
5
15
  ## v2.5.0rc0 (2024-09-10)
6
16
 
7
17
  ### Feat
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: idf-build-apps
3
- Version: 2.5.0rc0
3
+ Version: 2.5.0rc1
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
- # Configuration File `.idf-build-apps.toml`
1
+ # Configuration File `.idf_build_apps.toml`
2
2
 
3
3
  There are many CLI options available for `idf-build-apps`. While these options provide usage flexibility, they also make the CLI command too long and difficult to read. However, a configuration file allows defining all these options in a more readable and maintainable way.
4
4
 
@@ -0,0 +1,281 @@
1
+ #########################################
2
+ Manifest File ``.build-test-rules.yml``
3
+ #########################################
4
+
5
+ A ``.build-test-rules.yml`` file is the manifest file to control whether the app will be built or tested under the rules.
6
+
7
+ One typical manifest file look like this:
8
+
9
+ .. code:: yaml
10
+
11
+ [folder]:
12
+ enable:
13
+ - if: [if clause]
14
+ temporary: true # optional, default to false. `reason` is required if `temporary` is true
15
+ reason: [your reason] # optional
16
+ - ...
17
+ disable:
18
+ - if: [if clause]
19
+ - ...
20
+ disable_test:
21
+ - if: [if clause]
22
+ - ...
23
+
24
+ *******
25
+ Terms
26
+ *******
27
+
28
+ Supported Targets
29
+ =================
30
+
31
+ This refers to the targets that are fully supported by the ESP-IDF project. You may check the supported targets by running ``idf.py --list-targets``.
32
+
33
+ ``idf-build-apps`` will get this information dynamically from your ``$IDF_PATH``. For ESP-IDF release 5.3, the supported targets are:
34
+
35
+ - esp32
36
+ - esp32s2
37
+ - esp32c3
38
+ - esp32s3
39
+ - esp32c2
40
+ - esp32c6
41
+ - esp32h2
42
+ - esp32p4
43
+
44
+ Preview Targets
45
+ ===============
46
+
47
+ This refers to the targets that are still in preview status. You may check the preview targets by running ``idf.py --list-targets --preview``.
48
+
49
+ ``idf-build-apps`` will get this information dynamically from your ``$IDF_PATH``. For ESP-IDF release 5.3, the preview targets are:
50
+
51
+ - linux
52
+ - esp32c5
53
+ - esp32c61
54
+
55
+ ****************
56
+ ``if`` Clauses
57
+ ****************
58
+
59
+ Operands
60
+ ========
61
+
62
+ - Capitalized Words
63
+
64
+ - Variables defined in ``IDF_PATH/components/soc/[TARGET]/include/soc/*_caps.h`` or in ``IDF_PATH/components/esp_rom/[TARGET]/*_caps.h``. e.g., ``SOC_WIFI_SUPPORTED``, ``ESP_ROM_HAS_SPI_FLASH``
65
+ - ``IDF_TARGET``
66
+ - ``IDF_VERSION`` (IDF_VERSION_MAJOR.IDF_VERSION_MINOR.IDF_VERSION_PATCH. e.g., 5.2.0. Will convert to Version object to do a version comparison instead of a string comparison)
67
+ - ``IDF_VERSION_MAJOR``
68
+ - ``IDF_VERSION_MINOR``
69
+ - ``IDF_VERSION_PATCH``
70
+ - ``INCLUDE_DEFAULT`` (The default value of supported targets is 1, and the default value of preview targets is 0)
71
+ - ``CONFIG_NAME`` (config name defined in :doc:`../explanations/config_rules`)
72
+ - environment variables, default to ``0`` if not set
73
+
74
+ - String, must be double-quoted. e.g., ``"esp32"``, ``"12345"``
75
+
76
+ - Integer, support decimal and hex. e.g., ``1``, ``0xAB``
77
+
78
+ - List of strings or integers, or both types at the same time. e.g., ``["esp32", 1]``
79
+
80
+ Operators
81
+ =========
82
+
83
+ - ``==``, ``!=``, ``>``, ``>=``, ``<``, ``<=``
84
+ - ``and``, ``or``
85
+ - ``in``, ``not in`` with list
86
+ - parentheses
87
+
88
+ Limitations
89
+ ===========
90
+
91
+ All operators are binary operators. For more than two operands, you may use the nested parentheses trick. For example:
92
+
93
+ - ``A == 1 or (B == 2 and C in [1,2,3])``
94
+ - ``(A == 1 and B == 2) or (C not in ["3", "4", 5])``
95
+
96
+ .. warning::
97
+
98
+ Chained ``and`` and ``or`` operators are not supported. The operands start from the third one will be ignored.
99
+
100
+ For example, ``A == 1 and B == 2 and C == 3`` will be interpreted as ``A == 1 and B == 2``.
101
+
102
+ **********************
103
+ Enable/Disable Rules
104
+ **********************
105
+
106
+ By default, we enable build and test for all supported targets. In other words, all preview targets are disabled.
107
+
108
+ To simplify the manifest file, if an app needs to be build and tested on all supported targets, it does not need to be added in a manifest file. The manifest files are files that set the violation rules for apps.
109
+
110
+ Three rules (disable rules are calculated after the enable rules):
111
+
112
+ - ``enable``: run CI build/test jobs for targets that match any of the specified conditions only
113
+ - ``disable``: will not run CI build/test jobs for targets that match any of the specified conditions
114
+ - ``disable_test``: will not run CI test jobs for targets that match any of the specified conditions
115
+
116
+ Each key is a folder. The rule will recursively apply to all apps inside.
117
+
118
+ Overrides Rules
119
+ ===============
120
+
121
+ If one sub folder is in a special case, you can overwrite the rules for this folder by adding another entry for this folder itself. Each folder’s rules are standalone, and will not inherit its parent’s rules. (YAML inheritance is too complicated for reading)
122
+
123
+ For example, in the following code block, only ``disable`` rule exists in ``examples/foo/bar``. It’s unaware of its parent’s ``enable`` rule.
124
+
125
+ .. code:: yaml
126
+
127
+ examples/foo:
128
+ enable:
129
+ - if: IDF_TARGET == "esp32"
130
+
131
+ examples/foo/bar:
132
+ disable:
133
+ - if: IDF_TARGET == "esp32s2"
134
+
135
+ *******************
136
+ Practical Example
137
+ *******************
138
+
139
+ Here’s a practical example:
140
+
141
+ .. code:: yaml
142
+
143
+ examples/foo:
144
+ enable:
145
+ - if IDF_TARGET in ["esp32", 1, 2, 3]
146
+ - if IDF_TARGET not in ["4", "5", 6]
147
+ # should be run under all targets!
148
+
149
+ examples/bluetooth:
150
+ disable: # disable both build and tests jobs
151
+ - if: SOC_BT_SUPPORTED != 1
152
+ # reason is optional if there's no `temporary: true`
153
+ disable_test:
154
+ - if: IDF_TARGET == "esp32"
155
+ temporary: true
156
+ reason: lack of ci runners # required when `temporary: true`
157
+
158
+ examples/bluetooth/test_foo:
159
+ # each folder's settings are standalone
160
+ disable:
161
+ - if: IDF_TARGET == "esp32s2"
162
+ temporary: true
163
+ reason: no idea
164
+ # unlike examples/bluetooth, the apps under this folder would not be build nor test for "no idea" under target esp32s2
165
+
166
+ examples/get-started/hello_world:
167
+ enable:
168
+ - if: IDF_TARGET == "linux"
169
+ reason: this one only supports linux!
170
+
171
+ examples/get-started/blink:
172
+ enable:
173
+ - if: INCLUDE_DEFAULT == 1 or IDF_TARGET == "linux"
174
+ reason: This one supports all supported targets and linux
175
+
176
+ **********************
177
+ Enhanced YAML Syntax
178
+ **********************
179
+
180
+ Switch-Like Clauses
181
+ ===================
182
+
183
+ The Switch-Like clauses are supported by two keywords in the YAML file: ``depends_components`` and ``depends_filepatterns``.
184
+
185
+ Operands
186
+ --------
187
+
188
+ Switch cases have two main components: the ``if`` clause and the ``default`` clause. Just like a switch statement in c language, The first matched ``if`` clause will be applied. If no ``if`` clause matched, the ``default`` clause will be applied. Here’s an example:
189
+
190
+ .. code:: yaml
191
+
192
+ test1:
193
+ depends_components:
194
+ - if: IDF_VERSION == "{IDF_VERSION}"
195
+ content: [ "component_1" ]
196
+ - if: CONFIG_NAME == "AWESOME_CONFIG"
197
+ content: [ "component_2" ]
198
+ - default: [ "component_3", "component_4" ]
199
+
200
+ ``default`` clause is optional. If you don’t specify any ``default`` clause, it will return an empty array.
201
+
202
+ Limitations
203
+ -----------
204
+
205
+ You cannot combine a list and a switch in one node.
206
+
207
+ Reuse Lists
208
+ ===========
209
+
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
+
212
+ Array Elements as Strings
213
+ -------------------------
214
+
215
+ The following YAML code demonstrates how to reuse the elements from a list of strings:
216
+
217
+ .. code:: yaml
218
+
219
+ .base_depends_components: &base-depends-components
220
+ depends_components:
221
+ - esp_hw_support
222
+ - esp_rom
223
+ - esp_wifi
224
+
225
+ examples/wifi/coexist:
226
+ <<: *base-depends-components
227
+ depends_components+:
228
+ - esp_coex
229
+ depends_components-:
230
+ - esp_rom
231
+
232
+ After interpretation, the resulting YAML will be:
233
+
234
+ .. code:: yaml
235
+
236
+ examples/wifi/coexist:
237
+ depends_components:
238
+ - esp_hw_support
239
+ - esp_wifi
240
+ - esp_coex
241
+
242
+ This means that the ``esp_rom`` element is removed, and the ``esp_coex`` element is added to the ``depends_components`` list.
243
+
244
+ Array Elements as Dictionaries
245
+ ------------------------------
246
+
247
+ In addition to reuse elements from a list of strings, you can also perform these operations on a list of dictionaries. The matching is done based on the ``if`` key. Here’s an example:
248
+
249
+ .. code:: yaml
250
+
251
+ .base: &base
252
+ enable:
253
+ - if: IDF_VERSION == "5.2.0"
254
+ - if: IDF_VERSION == "5.3.0"
255
+
256
+ foo:
257
+ <<: *base
258
+ enable+:
259
+ # this if statement dictionary will override the one defined in `&base`
260
+ - if: IDF_VERSION == "5.2.0"
261
+ temp: true
262
+ - if: IDF_VERSION == "5.4.0"
263
+ reason: bar
264
+
265
+ After interpretation, the resulting YAML will be:
266
+
267
+ .. code:: yaml
268
+
269
+ foo:
270
+ enable:
271
+ - if: IDF_VERSION == "5.3.0"
272
+ - if: IDF_VERSION == "5.2.0"
273
+ temp: true
274
+ - if: IDF_VERSION == "5.4.0"
275
+ reason: bar
276
+
277
+ In this case, the ``enable`` list is extended with the new ``if`` statement and ``reason`` dictionary.
278
+
279
+ It’s important to note that the ``if`` dictionary defined in the ``+`` postfix will override the earlier one when the ``if`` statement matches.
280
+
281
+ This demonstrates how you can use the ``+`` and ``-`` postfixes to extend and remove elements from both string and dictionary lists in our YAML.
@@ -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.5.0rc0'
11
+ __version__ = '2.5.0rc1'
12
12
 
13
13
  from .session_args import (
14
14
  SessionArgs,
@@ -74,7 +74,6 @@ class App(BaseModel):
74
74
  NAME_PLACEHOLDER: t.ClassVar[str] = '@n' # replace it with self.name
75
75
  FULL_NAME_PLACEHOLDER: t.ClassVar[str] = '@f' # replace it with escaped self.app_dir
76
76
  IDF_VERSION_PLACEHOLDER: t.ClassVar[str] = '@v' # replace it with the IDF version
77
- PARALLEL_INDEX_PLACEHOLDER: t.ClassVar[str] = '@p' # replace it with the parallel index
78
77
  INDEX_PLACEHOLDER: t.ClassVar[str] = '@i' # replace it with the build index (while build_apps)
79
78
 
80
79
  SDKCONFIG_LINE_REGEX: t.ClassVar[t.Pattern] = re.compile(r'^([^=]+)=\"?([^\"\n]*)\"?\n*$')
@@ -115,7 +114,6 @@ class App(BaseModel):
115
114
  copy_sdkconfig: bool = False
116
115
 
117
116
  # build_apps() related
118
- parallel_index: t.Optional[int] = None # used for expand
119
117
  index: t.Optional[int] = None
120
118
 
121
119
  # build status related
@@ -244,8 +242,6 @@ class App(BaseModel):
244
242
 
245
243
  if self.index is not None:
246
244
  path = path.replace(self.INDEX_PLACEHOLDER, str(self.index))
247
- if self.parallel_index:
248
- path = path.replace(self.PARALLEL_INDEX_PLACEHOLDER, str(self.parallel_index))
249
245
  path = path.replace(
250
246
  self.IDF_VERSION_PLACEHOLDER, f'{IDF_VERSION_MAJOR}_{IDF_VERSION_MINOR}_{IDF_VERSION_PATCH}'
251
247
  )
@@ -760,22 +760,24 @@ class BuildArguments(FindBuildArguments):
760
760
  default=None,
761
761
  metadata=asdict(
762
762
  FieldMetadata(
763
- description='[INTERNAL CI USE] record size json filepath of the built apps to the specified file. '
763
+ description='Record size json filepath of the built apps to the specified file. '
764
764
  'Each line is a json string. Can expand placeholders @p',
765
765
  )
766
766
  ),
767
767
  )
768
+ _collect_size_info: t.Optional[str] = field(init=False, repr=False, default=None)
768
769
  collect_app_info: t.Optional[str] = field(
769
770
  default=None,
770
771
  metadata=asdict(
771
772
  FieldMetadata(
772
- description='[INTERNAL CI USE] record serialized app model of the built apps to the specified file. '
773
+ description='Record serialized app model of the built apps to the specified file. '
773
774
  'Each line is a json string. Can expand placeholders @p',
774
775
  )
775
776
  ),
776
777
  )
778
+ _collect_app_info: t.Optional[str] = field(init=False, repr=False, default=None)
777
779
  ignore_warning_str: InitVar[t.Optional[t.List[str]]] = _Field.UNSET
778
- ignore_warning_strings: t.Optional[t.List[str]] = field(
780
+ ignore_warning_strs: t.Optional[t.List[str]] = field(
779
781
  default=None,
780
782
  metadata=asdict(
781
783
  FieldMetadata(
@@ -816,6 +818,10 @@ class BuildArguments(FindBuildArguments):
816
818
  )
817
819
  ),
818
820
  )
821
+ _junitxml: t.Optional[str] = field(init=False, repr=False, default=None)
822
+
823
+ # used for expanding placeholders
824
+ PARALLEL_INDEX_PLACEHOLDER: t.ClassVar[str] = '@p' # replace it with the parallel index
819
825
 
820
826
  def __post_init__( # type: ignore
821
827
  self,
@@ -841,20 +847,71 @@ class BuildArguments(FindBuildArguments):
841
847
  config_rules_str=config_rules_str,
842
848
  )
843
849
 
844
- self.set_deprecated_field('ignore_warning_strings', 'ignore_warning_str', ignore_warning_str)
850
+ self.set_deprecated_field('ignore_warning_strs', 'ignore_warning_str', ignore_warning_str)
845
851
  self.set_deprecated_field('ignore_warning_files', 'ignore_warning_file', ignore_warning_file)
846
852
 
847
- self.ignore_warning_strings = to_list(self.ignore_warning_strings) or []
853
+ self.ignore_warning_strs = to_list(self.ignore_warning_strs) or []
848
854
 
849
855
  ignore_warnings_regexes = []
850
- if self.ignore_warning_strings:
851
- for s in self.ignore_warning_strings:
856
+ if self.ignore_warning_strs:
857
+ for s in self.ignore_warning_strs:
852
858
  ignore_warnings_regexes.append(re.compile(s))
853
859
  if self.ignore_warning_files:
854
860
  for s in self.ignore_warning_files:
855
861
  ignore_warnings_regexes.append(re.compile(s.strip()))
856
862
  App.IGNORE_WARNS_REGEXES = ignore_warnings_regexes
857
863
 
864
+ if not isinstance(BuildArguments.collect_size_info, property):
865
+ self._collect_size_info = self.collect_size_info
866
+ BuildArguments.collect_size_info = property( # type: ignore
867
+ BuildArguments._get_collect_size_info,
868
+ BuildArguments._set_collect_size_info,
869
+ )
870
+
871
+ if not isinstance(BuildArguments.collect_app_info, property):
872
+ self._collect_app_info = self.collect_app_info
873
+ BuildArguments.collect_app_info = property( # type: ignore
874
+ BuildArguments._get_collect_app_info,
875
+ BuildArguments._set_collect_app_info,
876
+ )
877
+
878
+ if not isinstance(BuildArguments.junitxml, property):
879
+ self._junitxml = self.junitxml
880
+ BuildArguments.junitxml = property( # type: ignore
881
+ BuildArguments._get_junitxml,
882
+ BuildArguments._set_junitxml,
883
+ )
884
+
885
+ def _get_collect_size_info(self) -> t.Optional[str]:
886
+ return (
887
+ self._collect_size_info.replace(self.PARALLEL_INDEX_PLACEHOLDER, str(self.parallel_index))
888
+ if self._collect_size_info
889
+ else None
890
+ )
891
+
892
+ def _set_collect_size_info(self, k: str) -> None:
893
+ self._collect_size_info = k
894
+
895
+ def _get_collect_app_info(self) -> t.Optional[str]:
896
+ return (
897
+ self._collect_app_info.replace(self.PARALLEL_INDEX_PLACEHOLDER, str(self.parallel_index))
898
+ if self._collect_app_info
899
+ else None
900
+ )
901
+
902
+ def _set_collect_app_info(self, k: str) -> None:
903
+ self._collect_app_info = k
904
+
905
+ def _get_junitxml(self) -> t.Optional[str]:
906
+ return (
907
+ self._junitxml.replace(self.PARALLEL_INDEX_PLACEHOLDER, str(self.parallel_index))
908
+ if self._junitxml
909
+ else None
910
+ )
911
+
912
+ def _set_junitxml(self, k: str) -> None:
913
+ self._junitxml = k
914
+
858
915
 
859
916
  @dataclass
860
917
  class DumpManifestShaArguments(GlobalArguments):
@@ -125,9 +125,6 @@ def build_apps(
125
125
  start, stop = get_parallel_start_stop(len(apps), build_arguments.parallel_count, build_arguments.parallel_index)
126
126
  LOGGER.info('Total %s apps. running build for app %s-%s', len(apps), start, stop)
127
127
 
128
- for app in apps[start - 1 : stop]: # we use 1-based
129
- app.parallel_index = build_arguments.parallel_index
130
-
131
128
  # cleanup collect files if exists at this early-stage
132
129
  for f in (build_arguments.collect_app_info, build_arguments.collect_size_info, build_arguments.junitxml):
133
130
  if f and os.path.isfile(f):
@@ -59,7 +59,7 @@ idf-build-apps = "idf_build_apps:main.main"
59
59
 
60
60
  [tool.commitizen]
61
61
  name = "cz_conventional_commits"
62
- version = "2.5.0rc0"
62
+ version = "2.5.0rc1"
63
63
  tag_format = "v$version"
64
64
  version_files = [
65
65
  "idf_build_apps/__init__.py",
@@ -29,7 +29,7 @@ entry_points = \
29
29
  {'console_scripts': ['idf-build-apps = idf_build_apps:main.main']}
30
30
 
31
31
  setup(name='idf-build-apps',
32
- version='2.5.0rc0',
32
+ version='2.5.0rc1',
33
33
  description='Tools for building ESP-IDF related apps.',
34
34
  author=None,
35
35
  author_email='Fu Hanxi <fuhanxi@espressif.com>',
@@ -2,7 +2,7 @@
2
2
  # SPDX-License-Identifier: Apache-2.0
3
3
 
4
4
 
5
- from idf_build_apps.args import DependencyDrivenBuildArguments, FindArguments, FindBuildArguments
5
+ from idf_build_apps.args import BuildArguments, DependencyDrivenBuildArguments, FindArguments, FindBuildArguments
6
6
  from idf_build_apps.config import IDF_BUILD_APPS_TOML_FN
7
7
 
8
8
 
@@ -38,7 +38,7 @@ def test_init_attr_override(capsys):
38
38
  assert (
39
39
  'Field `config` is deprecated. Will be removed in the next major release. ' 'Use field `config_rules` instead'
40
40
  ) in err_list[0]
41
- assert ('Field `config_rules` is already set. Ignoring deprecated field `config`') in err_list[1]
41
+ assert 'Field `config_rules` is already set. Ignoring deprecated field `config`' in err_list[1]
42
42
  assert (
43
43
  'Field `config_rules_str` is deprecated. Will be removed in the next major release. '
44
44
  'Use field `config_rules` instead'
@@ -64,3 +64,19 @@ no_color = true
64
64
  def test_empty_argument():
65
65
  args = FindArguments()
66
66
  assert args.config_rules is None
67
+
68
+
69
+ def test_build_args_expansion():
70
+ args = BuildArguments(parallel_index=2)
71
+
72
+ args.collect_app_info = '@p.txt'
73
+ assert args.collect_app_info == '2.txt'
74
+
75
+ args.parallel_index = 3
76
+ assert args.collect_app_info == '3.txt'
77
+
78
+ args.junitxml = 'x_@p.txt'
79
+ assert args.junitxml == 'x_3.txt'
80
+
81
+ args.collect_size_info = '@p_@p.txt'
82
+ assert args.collect_size_info == '3_3.txt'
@@ -1,245 +0,0 @@
1
- # Manifest File `.build-test-rules.yml`
2
-
3
- A `.build-test-rules.yml` file is the manifest file to control whether the app will be built or tested under the rules.
4
-
5
- One typical manifest file look like this:
6
-
7
- ```yaml
8
- [folder]:
9
- enable:
10
- - if: [if clause]
11
- temporary: true # optional, default to false. `reason` is required if `temporary` is true
12
- reason: [your reason] # optional
13
- - ...
14
- disable:
15
- - if: [if clause]
16
- - ...
17
- disable_test:
18
- - if: [if clause]
19
- - ...
20
- ```
21
-
22
- ## Terms
23
-
24
- ### Supported Targets
25
-
26
- This refers to the targets that are fully supported by the ESP-IDF project. You may check the supported targets by running `idf.py --list-targets`.
27
-
28
- `idf-build-apps` will get this information dynamically from your `$IDF_PATH`. For ESP-IDF release 5.3, the supported targets are:
29
-
30
- - esp32
31
- - esp32s2
32
- - esp32c3
33
- - esp32s3
34
- - esp32c2
35
- - esp32c6
36
- - esp32h2
37
- - esp32p4
38
-
39
- ### Preview Targets
40
-
41
- This refers to the targets that are still in preview status. You may check the preview targets by running `idf.py --list-targets --preview`.
42
-
43
- `idf-build-apps` will get this information dynamically from your `$IDF_PATH`. For ESP-IDF release 5.3, the preview targets are:
44
-
45
- - linux
46
- - esp32c5
47
- - esp32c61
48
-
49
- ## `if` Clauses
50
-
51
- ### Operands
52
-
53
- - Capitalized Words
54
- - Variables defined in `IDF_PATH/components/soc/[TARGET]/include/soc/*_caps.h` or in `IDF_PATH/components/esp_rom/[TARGET]/*_caps.h`. e.g., `SOC_WIFI_SUPPORTED`, `ESP_ROM_HAS_SPI_FLASH`
55
- - `IDF_TARGET`
56
- - `IDF_VERSION` (IDF_VERSION_MAJOR.IDF_VERSION_MINOR.IDF_VERSION_PATCH. e.g., 5.2.0. Will convert to Version object to do a version comparison instead of a string comparison)
57
- - `IDF_VERSION_MAJOR`
58
- - `IDF_VERSION_MINOR`
59
- - `IDF_VERSION_PATCH`
60
- - `INCLUDE_DEFAULT` (The default value of supported targets is 1, and the default value of preview targets is 0)
61
- - `CONFIG_NAME` (config name defined in [](project:#config-rules))
62
- - environment variables, default to `0` if not set
63
- - String, must be double-quoted. e.g., `"esp32"`, `"12345"`
64
- - Integer, support decimal and hex. e.g., `1`, `0xAB`
65
- - List of strings or integers, or both types at the same time. e.g., `["esp32", 1]`
66
-
67
- ### Operators
68
-
69
- - `==`, `!=`, `>`, `>=`, `<`, `<=`
70
- - `and`, `or`
71
- - `in`, `not in` with list
72
- - parentheses
73
-
74
- ### Limitations
75
-
76
- All operators are binary operators. For more than two operands, you may use the nested parentheses trick. For example:
77
-
78
- - `A == 1 or (B == 2 and C in [1,2,3])`
79
- - `(A == 1 and B == 2) or (C not in ["3", "4", 5])`
80
-
81
- ## Enable/Disable Rules
82
-
83
- By default, we enable build and test for all supported targets. In other words, all preview targets are disabled.
84
-
85
- To simplify the manifest file, if an app needs to be build and tested on all supported targets, it does not need to be added in a manifest file. The manifest files are files that set the violation rules for apps.
86
-
87
- Three rules (disable rules are calculated after the `enable` rule):
88
- - `enable`: run CI build/test jobs for targets that match any of the specified conditions only
89
- - `disable`: will not run CI build/test jobs for targets that match any of the specified conditions
90
- - `disable_test`: will not run CI test jobs for targets that match any of the specified conditions
91
-
92
- Each key is a folder. The rule will recursively apply to all apps inside.
93
-
94
- ### Overrides Rules
95
-
96
- If one sub folder is in a special case, you can overwrite the rules for this folder by adding another entry for this folder itself. Each folder's rules are standalone, and will not inherit its parent's rules. (YAML inheritance is too complicated for reading)
97
-
98
- For example, in the following code block, only `disable` rule exists in `examples/foo/bar`. It's unaware of its parent's `enable` rule.
99
-
100
- ```yaml
101
- examples/foo:
102
- enable:
103
- - if: IDF_TARGET == "esp32"
104
-
105
- examples/foo/bar:
106
- disable:
107
- - if: IDF_TARGET == "esp32s2"
108
- ```
109
-
110
- ## Practical Example
111
-
112
- Here's a practical example:
113
-
114
- ```yaml
115
- examples/foo:
116
- enable:
117
- - if IDF_TARGET in ["esp32", 1, 2, 3]
118
- - if IDF_TARGET not in ["4", "5", 6]
119
- # should be run under all targets!
120
-
121
- examples/bluetooth:
122
- disable: # disable both build and tests jobs
123
- - if: SOC_BT_SUPPORTED != 1
124
- # reason is optional if there's no `temporary: true`
125
- disable_test:
126
- - if: IDF_TARGET == "esp32"
127
- temporary: true
128
- reason: lack of ci runners # required when `temporary: true`
129
-
130
- examples/bluetooth/test_foo:
131
- # each folder's settings are standalone
132
- disable:
133
- - if: IDF_TARGET == "esp32s2"
134
- temporary: true
135
- reason: no idea
136
- # unlike examples/bluetooth, the apps under this folder would not be build nor test for "no idea" under target esp32s2
137
-
138
- examples/get-started/hello_world:
139
- enable:
140
- - if: IDF_TARGET == "linux"
141
- reason: this one only supports linux!
142
-
143
- examples/get-started/blink:
144
- enable:
145
- - if: INCLUDE_DEFAULT == 1 or IDF_TARGET == "linux"
146
- reason: This one supports all supported targets and linux
147
- ```
148
-
149
- ## Enhanced YAML Syntax
150
-
151
- ### Switch-Like Clauses
152
-
153
- The Switch-Like clauses are supported by two keywords in the YAML file: `depends_components` and `depends_filepatterns`.
154
-
155
- #### Operands
156
-
157
- Switch cases have two main components: the `if` clause and the `default` clause. Just like a switch statement in c language, The first matched `if` clause will be applied. If no `if` clause matched, the `default` clause will be applied. Here's an example:
158
-
159
- ```yaml
160
- test1:
161
- depends_components:
162
- - if: IDF_VERSION == "{IDF_VERSION}"
163
- content: [ "component_1" ]
164
- - if: CONFIG_NAME == "AWESOME_CONFIG"
165
- content: [ "component_2" ]
166
- - default: [ "component_3", "component_4" ]
167
- ```
168
-
169
- `default` clause is optional. If you don't specify any `default` clause, it will return an empty array.
170
-
171
- #### Limitations
172
-
173
- You cannot combine a list and a switch in one node.
174
-
175
- ### Reuse Lists
176
-
177
- To reuse the items defined in a list, you can use the `+` and `-` postfixes respectively. The order of calculation is always `+` first, followed by `-`.
178
-
179
- #### Array Elements as Strings
180
-
181
- The following YAML code demonstrates how to reuse the elements from a list of strings:
182
-
183
- ```yaml
184
- .base_depends_components: &base-depends-components
185
- depends_components:
186
- - esp_hw_support
187
- - esp_rom
188
- - esp_wifi
189
-
190
- examples/wifi/coexist:
191
- <<: *base-depends-components
192
- depends_components+:
193
- - esp_coex
194
- depends_components-:
195
- - esp_rom
196
- ```
197
-
198
- After interpretation, the resulting YAML will be:
199
-
200
- ```yaml
201
- examples/wifi/coexist:
202
- depends_components:
203
- - esp_hw_support
204
- - esp_wifi
205
- - esp_coex
206
- ```
207
-
208
- This means that the `esp_rom` element is removed, and the `esp_coex` element is added to the `depends_components` list.
209
-
210
- #### Array Elements as Dictionaries
211
-
212
- In addition to reuse elements from a list of strings, you can also perform these operations on a list of dictionaries. The matching is done based on the `if` key. Here's an example:
213
-
214
- ```yaml
215
- .base: &base
216
- enable:
217
- - if: IDF_VERSION == "5.2.0"
218
- - if: IDF_VERSION == "5.3.0"
219
-
220
- foo:
221
- <<: *base
222
- enable+:
223
- # this if statement dictionary will override the one defined in `&base`
224
- - if: IDF_VERSION == "5.2.0"
225
- temp: true
226
- - if: IDF_VERSION == "5.4.0"
227
- reason: bar
228
- ```
229
-
230
- After interpretation, the resulting YAML will be:
231
-
232
- ```yaml
233
- foo:
234
- enable:
235
- - if: IDF_VERSION == "5.3.0"
236
- - if: IDF_VERSION == "5.2.0"
237
- temp: true
238
- - if: IDF_VERSION == "5.4.0"
239
- reason: bar
240
- ```
241
-
242
- In this case, the `enable` list is extended with the new `if` statement and `reason` dictionary.
243
- It's important to note that the `if` dictionary defined in the `+` postfix will override the earlier one when the `if` statement matches.
244
-
245
- This demonstrates how you can use the `+` and `-` postfixes to extend and remove elements from both string and dictionary lists in our YAML.