idf-build-apps 2.10.1__tar.gz → 2.10.2__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.
- {idf_build_apps-2.10.1 → idf_build_apps-2.10.2}/.pre-commit-config.yaml +1 -1
- {idf_build_apps-2.10.1 → idf_build_apps-2.10.2}/CHANGELOG.md +7 -0
- {idf_build_apps-2.10.1 → idf_build_apps-2.10.2}/PKG-INFO +1 -1
- {idf_build_apps-2.10.1 → idf_build_apps-2.10.2}/idf_build_apps/__init__.py +1 -1
- {idf_build_apps-2.10.1 → idf_build_apps-2.10.2}/idf_build_apps/manifest/manifest.py +14 -4
- {idf_build_apps-2.10.1 → idf_build_apps-2.10.2}/pyproject.toml +1 -1
- {idf_build_apps-2.10.1 → idf_build_apps-2.10.2}/setup.py +1 -1
- idf_build_apps-2.10.2/tests/test_manifest.py +561 -0
- idf_build_apps-2.10.1/tests/test_manifest.py +0 -568
- {idf_build_apps-2.10.1 → idf_build_apps-2.10.2}/.editorconfig +0 -0
- {idf_build_apps-2.10.1 → idf_build_apps-2.10.2}/.git-blame-ignore-revs +0 -0
- {idf_build_apps-2.10.1 → idf_build_apps-2.10.2}/.gitattributes +0 -0
- {idf_build_apps-2.10.1 → idf_build_apps-2.10.2}/.github/dependabot.yml +0 -0
- {idf_build_apps-2.10.1 → idf_build_apps-2.10.2}/.github/workflows/publish-pypi.yml +0 -0
- {idf_build_apps-2.10.1 → idf_build_apps-2.10.2}/.github/workflows/sync-jira.yml +0 -0
- {idf_build_apps-2.10.1 → idf_build_apps-2.10.2}/.github/workflows/test-build-docs.yml +0 -0
- {idf_build_apps-2.10.1 → idf_build_apps-2.10.2}/.github/workflows/test-build-idf-apps.yml +0 -0
- {idf_build_apps-2.10.1 → idf_build_apps-2.10.2}/.gitignore +0 -0
- {idf_build_apps-2.10.1 → idf_build_apps-2.10.2}/.readthedocs.yml +0 -0
- {idf_build_apps-2.10.1 → idf_build_apps-2.10.2}/CONTRIBUTING.md +0 -0
- {idf_build_apps-2.10.1 → idf_build_apps-2.10.2}/LICENSE +0 -0
- {idf_build_apps-2.10.1 → idf_build_apps-2.10.2}/README.md +0 -0
- {idf_build_apps-2.10.1 → idf_build_apps-2.10.2}/docs/_apidoc_templates/module.rst_t +0 -0
- {idf_build_apps-2.10.1 → idf_build_apps-2.10.2}/docs/_apidoc_templates/package.rst_t +0 -0
- {idf_build_apps-2.10.1 → idf_build_apps-2.10.2}/docs/_apidoc_templates/toc.rst_t +0 -0
- {idf_build_apps-2.10.1 → idf_build_apps-2.10.2}/docs/_static/espressif-logo.svg +0 -0
- {idf_build_apps-2.10.1 → idf_build_apps-2.10.2}/docs/_static/theme_overrides.css +0 -0
- {idf_build_apps-2.10.1 → idf_build_apps-2.10.2}/docs/_templates/layout.html +0 -0
- {idf_build_apps-2.10.1 → idf_build_apps-2.10.2}/docs/conf_common.py +0 -0
- {idf_build_apps-2.10.1 → idf_build_apps-2.10.2}/docs/en/Makefile +0 -0
- {idf_build_apps-2.10.1 → idf_build_apps-2.10.2}/docs/en/conf.py +0 -0
- {idf_build_apps-2.10.1 → idf_build_apps-2.10.2}/docs/en/explanations/build.rst +0 -0
- {idf_build_apps-2.10.1 → idf_build_apps-2.10.2}/docs/en/explanations/config_rules.rst +0 -0
- {idf_build_apps-2.10.1 → idf_build_apps-2.10.2}/docs/en/explanations/dependency_driven_build.rst +0 -0
- {idf_build_apps-2.10.1 → idf_build_apps-2.10.2}/docs/en/explanations/find.rst +0 -0
- {idf_build_apps-2.10.1 → idf_build_apps-2.10.2}/docs/en/guides/1.x_to_2.x.md +0 -0
- {idf_build_apps-2.10.1 → idf_build_apps-2.10.2}/docs/en/guides/custom_app.md +0 -0
- {idf_build_apps-2.10.1 → idf_build_apps-2.10.2}/docs/en/index.rst +0 -0
- {idf_build_apps-2.10.1 → idf_build_apps-2.10.2}/docs/en/others/CHANGELOG.md +0 -0
- {idf_build_apps-2.10.1 → idf_build_apps-2.10.2}/docs/en/others/CONTRIBUTING.md +0 -0
- {idf_build_apps-2.10.1 → idf_build_apps-2.10.2}/docs/en/references/cli.rst +0 -0
- {idf_build_apps-2.10.1 → idf_build_apps-2.10.2}/docs/en/references/config_file.rst +0 -0
- {idf_build_apps-2.10.1 → idf_build_apps-2.10.2}/docs/en/references/manifest.rst +0 -0
- {idf_build_apps-2.10.1 → idf_build_apps-2.10.2}/idf_build_apps/__main__.py +0 -0
- {idf_build_apps-2.10.1 → idf_build_apps-2.10.2}/idf_build_apps/app.py +0 -0
- {idf_build_apps-2.10.1 → idf_build_apps-2.10.2}/idf_build_apps/args.py +0 -0
- {idf_build_apps-2.10.1 → idf_build_apps-2.10.2}/idf_build_apps/autocompletions.py +0 -0
- {idf_build_apps-2.10.1 → idf_build_apps-2.10.2}/idf_build_apps/constants.py +0 -0
- {idf_build_apps-2.10.1 → idf_build_apps-2.10.2}/idf_build_apps/finder.py +0 -0
- {idf_build_apps-2.10.1 → idf_build_apps-2.10.2}/idf_build_apps/junit/__init__.py +0 -0
- {idf_build_apps-2.10.1 → idf_build_apps-2.10.2}/idf_build_apps/junit/report.py +0 -0
- {idf_build_apps-2.10.1 → idf_build_apps-2.10.2}/idf_build_apps/junit/utils.py +0 -0
- {idf_build_apps-2.10.1 → idf_build_apps-2.10.2}/idf_build_apps/log.py +0 -0
- {idf_build_apps-2.10.1 → idf_build_apps-2.10.2}/idf_build_apps/main.py +0 -0
- {idf_build_apps-2.10.1 → idf_build_apps-2.10.2}/idf_build_apps/manifest/__init__.py +0 -0
- {idf_build_apps-2.10.1 → idf_build_apps-2.10.2}/idf_build_apps/manifest/soc_header.py +0 -0
- {idf_build_apps-2.10.1 → idf_build_apps-2.10.2}/idf_build_apps/py.typed +0 -0
- {idf_build_apps-2.10.1 → idf_build_apps-2.10.2}/idf_build_apps/session_args.py +0 -0
- {idf_build_apps-2.10.1 → idf_build_apps-2.10.2}/idf_build_apps/utils.py +0 -0
- {idf_build_apps-2.10.1 → idf_build_apps-2.10.2}/idf_build_apps/vendors/__init__.py +0 -0
- {idf_build_apps-2.10.1 → idf_build_apps-2.10.2}/idf_build_apps/vendors/pydantic_sources.py +0 -0
- {idf_build_apps-2.10.1 → idf_build_apps-2.10.2}/idf_build_apps/yaml/__init__.py +0 -0
- {idf_build_apps-2.10.1 → idf_build_apps-2.10.2}/idf_build_apps/yaml/parser.py +0 -0
- {idf_build_apps-2.10.1 → idf_build_apps-2.10.2}/license_header.txt +0 -0
- {idf_build_apps-2.10.1 → idf_build_apps-2.10.2}/tests/conftest.py +0 -0
- {idf_build_apps-2.10.1 → idf_build_apps-2.10.2}/tests/test_app.py +0 -0
- {idf_build_apps-2.10.1 → idf_build_apps-2.10.2}/tests/test_args.py +0 -0
- {idf_build_apps-2.10.1 → idf_build_apps-2.10.2}/tests/test_build.py +0 -0
- {idf_build_apps-2.10.1 → idf_build_apps-2.10.2}/tests/test_cmd.py +0 -0
- {idf_build_apps-2.10.1 → idf_build_apps-2.10.2}/tests/test_finder.py +0 -0
- {idf_build_apps-2.10.1 → idf_build_apps-2.10.2}/tests/test_utils.py +0 -0
|
@@ -2,6 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## v2.10.2 (2025-05-22)
|
|
6
|
+
|
|
7
|
+
### Perf
|
|
8
|
+
|
|
9
|
+
- `most_suitable_rule` stop searching till reached root dir
|
|
10
|
+
- pre-compute rules folder, reduced 50% time on `most_suitable_rule`
|
|
11
|
+
|
|
5
12
|
## v2.10.1 (2025-05-05)
|
|
6
13
|
|
|
7
14
|
### Fix
|
|
@@ -254,9 +254,11 @@ class Manifest:
|
|
|
254
254
|
|
|
255
255
|
def __init__(self, rules: t.Iterable[FolderRule], *, root_path: str = os.curdir) -> None:
|
|
256
256
|
self.rules = sorted(rules, key=lambda x: x.folder)
|
|
257
|
-
|
|
258
257
|
self._root_path = to_absolute_path(root_path)
|
|
259
258
|
|
|
259
|
+
# Pre-compute rule paths
|
|
260
|
+
self._rule_paths = {rule.folder: rule for rule in self.rules}
|
|
261
|
+
|
|
260
262
|
@classmethod
|
|
261
263
|
def from_files(cls, paths: t.Iterable[PathLike], *, root_path: str = os.curdir) -> 'Manifest':
|
|
262
264
|
"""
|
|
@@ -383,9 +385,17 @@ class Manifest:
|
|
|
383
385
|
|
|
384
386
|
def most_suitable_rule(self, _folder: str) -> FolderRule:
|
|
385
387
|
folder = to_absolute_path(_folder)
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
388
|
+
|
|
389
|
+
while True:
|
|
390
|
+
if folder in self._rule_paths:
|
|
391
|
+
return self._rule_paths[folder]
|
|
392
|
+
folder = os.path.dirname(folder)
|
|
393
|
+
|
|
394
|
+
# reached the root path, stop searching
|
|
395
|
+
if folder == self._root_path:
|
|
396
|
+
if folder in self._rule_paths:
|
|
397
|
+
return self._rule_paths[folder]
|
|
398
|
+
break
|
|
389
399
|
|
|
390
400
|
return DefaultRule(folder)
|
|
391
401
|
|
|
@@ -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.10.
|
|
41
|
+
version='2.10.2',
|
|
42
42
|
description='Tools for building ESP-IDF related apps.',
|
|
43
43
|
author=None,
|
|
44
44
|
author_email='Fu Hanxi <fuhanxi@espressif.com>',
|
|
@@ -0,0 +1,561 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
|
2
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
import os
|
|
4
|
+
|
|
5
|
+
import esp_bool_parser
|
|
6
|
+
import pytest
|
|
7
|
+
import yaml
|
|
8
|
+
from esp_bool_parser.utils import to_version
|
|
9
|
+
|
|
10
|
+
import idf_build_apps
|
|
11
|
+
from idf_build_apps import setup_logging
|
|
12
|
+
from idf_build_apps.constants import (
|
|
13
|
+
SUPPORTED_TARGETS,
|
|
14
|
+
)
|
|
15
|
+
from idf_build_apps.manifest.manifest import (
|
|
16
|
+
IfClause,
|
|
17
|
+
Manifest,
|
|
18
|
+
)
|
|
19
|
+
from idf_build_apps.utils import (
|
|
20
|
+
InvalidIfClause,
|
|
21
|
+
InvalidManifest,
|
|
22
|
+
)
|
|
23
|
+
from idf_build_apps.yaml import (
|
|
24
|
+
parse,
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class TestManifest:
|
|
29
|
+
@pytest.fixture(autouse=True)
|
|
30
|
+
def _setup_version(self, monkeypatch):
|
|
31
|
+
"""Setup ESP-IDF version for all tests in this class."""
|
|
32
|
+
monkeypatch.setattr(esp_bool_parser.constants, 'IDF_VERSION', to_version('5.9.0'))
|
|
33
|
+
monkeypatch.setattr(esp_bool_parser.constants, 'IDF_VERSION_MAJOR', 5)
|
|
34
|
+
monkeypatch.setattr(esp_bool_parser.constants, 'IDF_VERSION_MINOR', 9)
|
|
35
|
+
monkeypatch.setattr(esp_bool_parser.constants, 'IDF_VERSION_PATCH', 0)
|
|
36
|
+
|
|
37
|
+
def test_manifest_from_file_warning(self, tmp_path, capsys, monkeypatch):
|
|
38
|
+
setup_logging()
|
|
39
|
+
yaml_file = tmp_path / 'test.yml'
|
|
40
|
+
yaml_file.write_text(
|
|
41
|
+
"""
|
|
42
|
+
test1:
|
|
43
|
+
enable:
|
|
44
|
+
- if: IDF_TARGET == "esp32" or IDF_TARGET == "esp32c3"
|
|
45
|
+
- if: IDF_TARGET == "esp32s2" and IDF_VERSION_MAJOR in [4, 5]
|
|
46
|
+
disable_test:
|
|
47
|
+
- if: IDF_TARGET == "esp32c3"
|
|
48
|
+
|
|
49
|
+
test2:
|
|
50
|
+
enable:
|
|
51
|
+
- if: INCLUDE_DEFAULT == 0 and IDF_TARGET == "linux"
|
|
52
|
+
""",
|
|
53
|
+
encoding='utf8',
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
manifest = Manifest.from_file(yaml_file, root_path=tmp_path)
|
|
57
|
+
captured_err = capsys.readouterr().err.splitlines()
|
|
58
|
+
msg_fmt = 'Folder "{}" does not exist. Please check your manifest file {}'
|
|
59
|
+
# two warnings warn test1 test2 not exists
|
|
60
|
+
assert len(captured_err) == 2
|
|
61
|
+
assert msg_fmt.format(os.path.join(tmp_path, 'test1'), yaml_file) in captured_err[0]
|
|
62
|
+
assert msg_fmt.format(os.path.join(tmp_path, 'test2'), yaml_file) in captured_err[1]
|
|
63
|
+
|
|
64
|
+
assert manifest.enable_build_targets('test1') == ['esp32', 'esp32c3', 'esp32s2']
|
|
65
|
+
assert manifest.enable_test_targets('test1') == ['esp32', 'esp32s2']
|
|
66
|
+
assert manifest.enable_build_targets('test2') == ['linux']
|
|
67
|
+
assert manifest.enable_test_targets('test2') == ['linux']
|
|
68
|
+
|
|
69
|
+
monkeypatch.setattr(idf_build_apps.manifest.manifest.Manifest, 'CHECK_MANIFEST_RULES', True)
|
|
70
|
+
with pytest.raises(InvalidManifest, match=msg_fmt.format(os.path.join(tmp_path, 'test1'), yaml_file)):
|
|
71
|
+
Manifest.from_file(yaml_file, root_path=tmp_path)
|
|
72
|
+
|
|
73
|
+
# test with folder that has the same prefix as one of the folders in the manifest
|
|
74
|
+
assert manifest.enable_build_targets('test23') == sorted(SUPPORTED_TARGETS)
|
|
75
|
+
|
|
76
|
+
def test_repr(self, tmp_path):
|
|
77
|
+
yaml_file = tmp_path / 'test.yml'
|
|
78
|
+
|
|
79
|
+
yaml_file.write_text(
|
|
80
|
+
"""
|
|
81
|
+
test1:
|
|
82
|
+
enable:
|
|
83
|
+
- if: IDF_TARGET == "esp32c3"
|
|
84
|
+
reason: "None"
|
|
85
|
+
depends_components:
|
|
86
|
+
- if: IDF_VERSION == "1.2.3" or IDF_VERSION_MAJOR == 4
|
|
87
|
+
content: [ "VVV" ]
|
|
88
|
+
- if: CONFIG_NAME == "AAA"
|
|
89
|
+
content: [ "AAA" ]
|
|
90
|
+
- default: ["some_1", "some_2", "some_3"]
|
|
91
|
+
|
|
92
|
+
""",
|
|
93
|
+
encoding='utf8',
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
manifest = Manifest.from_file(yaml_file)
|
|
97
|
+
manifest_rule = manifest.rules[0]
|
|
98
|
+
assert (
|
|
99
|
+
repr(manifest_rule.enable)
|
|
100
|
+
== """[IfClause(stmt='IDF_TARGET == "esp32c3"', temporary=False, reason='None')]"""
|
|
101
|
+
)
|
|
102
|
+
assert (
|
|
103
|
+
repr(manifest_rule.depends_components)
|
|
104
|
+
== """SwitchClause(if_clauses=[IfClause(stmt='IDF_VERSION == "1.2.3" or IDF_VERSION_MAJOR == 4', temporary=False, reason=None), IfClause(stmt='CONFIG_NAME == "AAA"', temporary=False, reason=None)], contents=[['VVV'], ['AAA']], default_clause=['some_1', 'some_2', 'some_3'])""" # noqa
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
def test_manifest_switch_clause(self, tmp_path):
|
|
108
|
+
yaml_file = tmp_path / 'test.yml'
|
|
109
|
+
yaml_file.write_text(
|
|
110
|
+
"""
|
|
111
|
+
test1:
|
|
112
|
+
depends_components:
|
|
113
|
+
- if: IDF_VERSION == "5.9.0"
|
|
114
|
+
content: [ "VVV" ]
|
|
115
|
+
- if: CONFIG_NAME == "AAA"
|
|
116
|
+
content: [ "AAA" ]
|
|
117
|
+
- default: ["some_1", "some_2", "some_3"]
|
|
118
|
+
|
|
119
|
+
test2:
|
|
120
|
+
depends_components:
|
|
121
|
+
- if: IDF_TARGET == "esp32"
|
|
122
|
+
content: [ "esp32" ]
|
|
123
|
+
- if: CONFIG_NAME == "AAA"
|
|
124
|
+
content: [ "AAA" ]
|
|
125
|
+
- if: IDF_VERSION == "5.9.0"
|
|
126
|
+
content: [ "VVV" ]
|
|
127
|
+
- default: ["some_1", "some_2", "some_3"]
|
|
128
|
+
|
|
129
|
+
test3:
|
|
130
|
+
depends_components:
|
|
131
|
+
- if: CONFIG_NAME == "AAA"
|
|
132
|
+
content: [ "AAA" ]
|
|
133
|
+
- if: CONFIG_NAME == "BBB"
|
|
134
|
+
content: [ "BBB" ]
|
|
135
|
+
- default: ["some_1", "some_2", "some_3"]
|
|
136
|
+
|
|
137
|
+
test4:
|
|
138
|
+
depends_components:
|
|
139
|
+
- if: CONFIG_NAME == "BBB"
|
|
140
|
+
content: [ "BBB" ]
|
|
141
|
+
- if: CONFIG_NAME == "AAA"
|
|
142
|
+
content: [ "AAA" ]
|
|
143
|
+
|
|
144
|
+
test5:
|
|
145
|
+
depends_components:
|
|
146
|
+
- "some_1"
|
|
147
|
+
- "some_2"
|
|
148
|
+
- "some_3"
|
|
149
|
+
|
|
150
|
+
""",
|
|
151
|
+
encoding='utf8',
|
|
152
|
+
)
|
|
153
|
+
|
|
154
|
+
manifest = Manifest.from_file(yaml_file)
|
|
155
|
+
|
|
156
|
+
assert manifest.depends_components('test1', None, None) == ['VVV']
|
|
157
|
+
assert manifest.depends_components('test1', None, 'AAA') == ['VVV']
|
|
158
|
+
|
|
159
|
+
assert manifest.depends_components('test2', 'esp32', None) == ['esp32']
|
|
160
|
+
assert manifest.depends_components('test2', None, 'AAA') == ['AAA']
|
|
161
|
+
assert manifest.depends_components('test2', 'esp32', 'AAA') == ['esp32']
|
|
162
|
+
assert manifest.depends_components('test2', None, None) == ['VVV']
|
|
163
|
+
|
|
164
|
+
assert manifest.depends_components('test3', 'esp32', 'AAA') == ['AAA']
|
|
165
|
+
assert manifest.depends_components('test3', 'esp32', 'BBB') == ['BBB']
|
|
166
|
+
assert manifest.depends_components('test3', 'esp32', '123123') == ['some_1', 'some_2', 'some_3']
|
|
167
|
+
assert manifest.depends_components('test3', None, None) == ['some_1', 'some_2', 'some_3']
|
|
168
|
+
|
|
169
|
+
assert manifest.depends_components('test4', 'esp32', 'AAA') == ['AAA']
|
|
170
|
+
assert manifest.depends_components('test4', 'esp32', 'BBB') == ['BBB']
|
|
171
|
+
assert manifest.depends_components('test4', 'esp32', '123123') == []
|
|
172
|
+
assert manifest.depends_components('test4', None, None) == []
|
|
173
|
+
|
|
174
|
+
assert manifest.depends_components('test5', 'esp32', 'AAA') == ['some_1', 'some_2', 'some_3']
|
|
175
|
+
assert manifest.depends_components('test5', 'esp32', 'BBB') == ['some_1', 'some_2', 'some_3']
|
|
176
|
+
assert manifest.depends_components('test5', 'esp32', '123123') == ['some_1', 'some_2', 'some_3']
|
|
177
|
+
assert manifest.depends_components('test5', None, None) == ['some_1', 'some_2', 'some_3']
|
|
178
|
+
|
|
179
|
+
def test_manifest_switch_clause_with_postfix(self, tmp_path):
|
|
180
|
+
yaml_file = tmp_path / 'test.yml'
|
|
181
|
+
|
|
182
|
+
yaml_file.write_text(
|
|
183
|
+
"""
|
|
184
|
+
.test: &test
|
|
185
|
+
depends_components+:
|
|
186
|
+
- if: CONFIG_NAME == "AAA"
|
|
187
|
+
content: ["NEW_AAA"]
|
|
188
|
+
- if: CONFIG_NAME == "BBB"
|
|
189
|
+
content: ["NEW_BBB"]
|
|
190
|
+
depends_components-:
|
|
191
|
+
- if: CONFIG_NAME == "CCC"
|
|
192
|
+
|
|
193
|
+
test1:
|
|
194
|
+
<<: *test
|
|
195
|
+
depends_components:
|
|
196
|
+
- if: CONFIG_NAME == "AAA"
|
|
197
|
+
content: [ "AAA" ]
|
|
198
|
+
- if: CONFIG_NAME == "CCC"
|
|
199
|
+
content: [ "CCC" ]
|
|
200
|
+
- default: ["DF"]
|
|
201
|
+
""",
|
|
202
|
+
encoding='utf8',
|
|
203
|
+
)
|
|
204
|
+
manifest = Manifest.from_file(yaml_file, root_path=tmp_path)
|
|
205
|
+
|
|
206
|
+
assert manifest.depends_components('test1', None, None) == ['DF']
|
|
207
|
+
assert manifest.depends_components('test1', None, 'CCC') == ['DF']
|
|
208
|
+
assert manifest.depends_components('test1', None, 'AAA') == ['NEW_AAA']
|
|
209
|
+
assert manifest.depends_components('test1', None, 'BBB') == ['NEW_BBB']
|
|
210
|
+
|
|
211
|
+
def test_manifest_switch_clause_wrong_manifest_format(self, tmp_path):
|
|
212
|
+
yaml_file = tmp_path / 'test.yml'
|
|
213
|
+
|
|
214
|
+
yaml_file.write_text(
|
|
215
|
+
"""
|
|
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
|
|
222
|
+
|
|
223
|
+
""",
|
|
224
|
+
encoding='utf8',
|
|
225
|
+
)
|
|
226
|
+
try:
|
|
227
|
+
with pytest.warns(UserWarning, match='Folder ".+" does not exist. Please check your manifest file'):
|
|
228
|
+
Manifest.from_file(yaml_file)
|
|
229
|
+
except InvalidManifest as e:
|
|
230
|
+
assert str(e) == "Only the 'if' and 'default' keywords are supported in switch clause."
|
|
231
|
+
|
|
232
|
+
yaml_file.write_text(
|
|
233
|
+
"""
|
|
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
|
|
241
|
+
""",
|
|
242
|
+
encoding='utf8',
|
|
243
|
+
)
|
|
244
|
+
try:
|
|
245
|
+
Manifest.from_file(yaml_file)
|
|
246
|
+
except InvalidManifest as e:
|
|
247
|
+
assert str(e) == 'Current manifest format has to fit either the switch format or the list format.'
|
|
248
|
+
|
|
249
|
+
def test_manifest_with_anchor(self, tmp_path, monkeypatch):
|
|
250
|
+
yaml_file = tmp_path / 'test.yml'
|
|
251
|
+
yaml_file.write_text(
|
|
252
|
+
"""
|
|
253
|
+
.base: &base
|
|
254
|
+
depends_components:
|
|
255
|
+
- a
|
|
256
|
+
|
|
257
|
+
foo: &foo
|
|
258
|
+
<<: *base
|
|
259
|
+
disable:
|
|
260
|
+
- if: IDF_TARGET == "esp32"
|
|
261
|
+
|
|
262
|
+
bar:
|
|
263
|
+
<<: *foo
|
|
264
|
+
""",
|
|
265
|
+
encoding='utf8',
|
|
266
|
+
)
|
|
267
|
+
|
|
268
|
+
monkeypatch.setattr(idf_build_apps.manifest.manifest.FolderRule, 'DEFAULT_BUILD_TARGETS', ['esp32'])
|
|
269
|
+
manifest = Manifest.from_file(yaml_file)
|
|
270
|
+
assert manifest.enable_build_targets('bar') == []
|
|
271
|
+
|
|
272
|
+
def test_manifest_with_anchor_and_postfix(self, tmp_path):
|
|
273
|
+
yaml_file = tmp_path / 'test.yml'
|
|
274
|
+
|
|
275
|
+
yaml_file.write_text(
|
|
276
|
+
"""
|
|
277
|
+
foo:
|
|
278
|
+
""",
|
|
279
|
+
encoding='utf8',
|
|
280
|
+
)
|
|
281
|
+
manifest = Manifest.from_file(yaml_file)
|
|
282
|
+
assert manifest.enable_build_targets('foo') == sorted(SUPPORTED_TARGETS)
|
|
283
|
+
|
|
284
|
+
yaml_file.write_text(
|
|
285
|
+
"""
|
|
286
|
+
.base_depends_components: &base-depends-components
|
|
287
|
+
depends_components:
|
|
288
|
+
- esp_hw_support
|
|
289
|
+
- esp_rom
|
|
290
|
+
- esp_wifi
|
|
291
|
+
|
|
292
|
+
examples/wifi/coexist:
|
|
293
|
+
<<: *base-depends-components
|
|
294
|
+
depends_components+:
|
|
295
|
+
- esp_coex
|
|
296
|
+
depends_components-:
|
|
297
|
+
- esp_rom
|
|
298
|
+
""",
|
|
299
|
+
encoding='utf8',
|
|
300
|
+
)
|
|
301
|
+
|
|
302
|
+
manifest = Manifest.from_file(yaml_file)
|
|
303
|
+
assert manifest.depends_components('examples/wifi/coexist') == ['esp_coex', 'esp_hw_support', 'esp_wifi']
|
|
304
|
+
|
|
305
|
+
yaml_file.write_text(
|
|
306
|
+
"""
|
|
307
|
+
.base: &base
|
|
308
|
+
enable:
|
|
309
|
+
- if: IDF_VERSION == "5.2.0"
|
|
310
|
+
- if: IDF_VERSION == "5.3.0"
|
|
311
|
+
|
|
312
|
+
foo:
|
|
313
|
+
<<: *base
|
|
314
|
+
enable+:
|
|
315
|
+
- if: IDF_VERSION == "5.2.0"
|
|
316
|
+
temp: true
|
|
317
|
+
- if: IDF_VERSION == "5.4.0"
|
|
318
|
+
reason: bar
|
|
319
|
+
""",
|
|
320
|
+
encoding='utf8',
|
|
321
|
+
)
|
|
322
|
+
s_manifest_dict = parse(yaml_file)
|
|
323
|
+
|
|
324
|
+
yaml_file.write_text(
|
|
325
|
+
"""
|
|
326
|
+
foo:
|
|
327
|
+
enable:
|
|
328
|
+
- if: IDF_VERSION == "5.3.0"
|
|
329
|
+
- if: IDF_VERSION == "5.2.0"
|
|
330
|
+
temp: true
|
|
331
|
+
- if: IDF_VERSION == "5.4.0"
|
|
332
|
+
reason: bar
|
|
333
|
+
""",
|
|
334
|
+
encoding='utf8',
|
|
335
|
+
)
|
|
336
|
+
with open(yaml_file) as f:
|
|
337
|
+
manifest_dict = yaml.safe_load(f) or {}
|
|
338
|
+
|
|
339
|
+
assert s_manifest_dict['foo'] == manifest_dict['foo']
|
|
340
|
+
|
|
341
|
+
yaml_file.write_text(
|
|
342
|
+
"""
|
|
343
|
+
.base: &base
|
|
344
|
+
enable:
|
|
345
|
+
- if: IDF_VERSION == "5.3.0"
|
|
346
|
+
|
|
347
|
+
foo:
|
|
348
|
+
<<: *base
|
|
349
|
+
enable+:
|
|
350
|
+
- if: IDF_VERSION == "5.2.0"
|
|
351
|
+
temp: true
|
|
352
|
+
- if: IDF_VERSION == "5.4.0"
|
|
353
|
+
reason: bar
|
|
354
|
+
""",
|
|
355
|
+
encoding='utf8',
|
|
356
|
+
)
|
|
357
|
+
|
|
358
|
+
s_manifest_dict = parse(yaml_file)
|
|
359
|
+
|
|
360
|
+
yaml_file.write_text(
|
|
361
|
+
"""
|
|
362
|
+
foo:
|
|
363
|
+
enable:
|
|
364
|
+
- if: IDF_VERSION == "5.3.0"
|
|
365
|
+
- if: IDF_VERSION == "5.2.0"
|
|
366
|
+
temp: true
|
|
367
|
+
- if: IDF_VERSION == "5.4.0"
|
|
368
|
+
reason: bar
|
|
369
|
+
""",
|
|
370
|
+
encoding='utf8',
|
|
371
|
+
)
|
|
372
|
+
with open(yaml_file) as f:
|
|
373
|
+
manifest_dict = yaml.safe_load(f) or {}
|
|
374
|
+
|
|
375
|
+
assert s_manifest_dict['foo'] == manifest_dict['foo']
|
|
376
|
+
|
|
377
|
+
yaml_file.write_text(
|
|
378
|
+
"""
|
|
379
|
+
.test: &test
|
|
380
|
+
depends_components:
|
|
381
|
+
- a
|
|
382
|
+
- b
|
|
383
|
+
|
|
384
|
+
foo:
|
|
385
|
+
<<: *test
|
|
386
|
+
depends_components+:
|
|
387
|
+
- c
|
|
388
|
+
|
|
389
|
+
bar:
|
|
390
|
+
<<: *test
|
|
391
|
+
depends_components+:
|
|
392
|
+
- d
|
|
393
|
+
""",
|
|
394
|
+
encoding='utf8',
|
|
395
|
+
)
|
|
396
|
+
s_manifest_dict = parse(yaml_file)
|
|
397
|
+
foo = s_manifest_dict['foo']
|
|
398
|
+
bar = s_manifest_dict['bar']
|
|
399
|
+
assert foo['depends_components'] == ['a', 'b', 'c']
|
|
400
|
+
assert bar['depends_components'] == ['a', 'b', 'd']
|
|
401
|
+
assert id(foo['depends_components']) != id(bar['depends_components'])
|
|
402
|
+
|
|
403
|
+
yaml_file.write_text(
|
|
404
|
+
"""
|
|
405
|
+
.test: &test
|
|
406
|
+
depends_components:
|
|
407
|
+
- if: 1
|
|
408
|
+
value: 123
|
|
409
|
+
|
|
410
|
+
foo:
|
|
411
|
+
<<: *test
|
|
412
|
+
depends_components+:
|
|
413
|
+
- if: 2
|
|
414
|
+
value: 234
|
|
415
|
+
|
|
416
|
+
bar:
|
|
417
|
+
<<: *test
|
|
418
|
+
depends_components+:
|
|
419
|
+
- if: 2
|
|
420
|
+
value: 345
|
|
421
|
+
""",
|
|
422
|
+
encoding='utf8',
|
|
423
|
+
)
|
|
424
|
+
s_manifest_dict = parse(yaml_file)
|
|
425
|
+
foo = s_manifest_dict['foo']
|
|
426
|
+
bar = s_manifest_dict['bar']
|
|
427
|
+
assert id(foo['depends_components']) != id(bar['depends_components'])
|
|
428
|
+
print(s_manifest_dict)
|
|
429
|
+
|
|
430
|
+
def test_manifest_postfix_order(self, tmp_path):
|
|
431
|
+
yaml_file = tmp_path / 'test.yml'
|
|
432
|
+
yaml_file.write_text(
|
|
433
|
+
"""
|
|
434
|
+
.base_depends_components: &base-depends-components
|
|
435
|
+
depends_components:
|
|
436
|
+
- esp_hw_support
|
|
437
|
+
|
|
438
|
+
examples/wifi/coexist:
|
|
439
|
+
<<: *base-depends-components
|
|
440
|
+
depends_components+:
|
|
441
|
+
- esp_coex
|
|
442
|
+
depends_components-:
|
|
443
|
+
- esp_coex
|
|
444
|
+
""",
|
|
445
|
+
encoding='utf8',
|
|
446
|
+
)
|
|
447
|
+
|
|
448
|
+
manifest = Manifest.from_file(yaml_file)
|
|
449
|
+
assert manifest.depends_components('examples/wifi/coexist') == ['esp_hw_support']
|
|
450
|
+
|
|
451
|
+
def test_from_files_duplicates(self, tmp_path, monkeypatch):
|
|
452
|
+
yaml_file_1 = tmp_path / 'test1.yml'
|
|
453
|
+
yaml_file_1.write_text(
|
|
454
|
+
"""
|
|
455
|
+
foo:
|
|
456
|
+
enable:
|
|
457
|
+
- if: IDF_TARGET == "esp32"
|
|
458
|
+
""",
|
|
459
|
+
encoding='utf8',
|
|
460
|
+
)
|
|
461
|
+
|
|
462
|
+
yaml_file_2 = tmp_path / 'test2.yml'
|
|
463
|
+
yaml_file_2.write_text(
|
|
464
|
+
"""
|
|
465
|
+
foo:
|
|
466
|
+
enable:
|
|
467
|
+
- if: IDF_TARGET == "esp32"
|
|
468
|
+
""",
|
|
469
|
+
encoding='utf8',
|
|
470
|
+
)
|
|
471
|
+
|
|
472
|
+
monkeypatch.setattr(idf_build_apps.manifest.manifest.Manifest, 'CHECK_MANIFEST_RULES', True)
|
|
473
|
+
folder_path = os.path.join(os.getcwd(), 'foo')
|
|
474
|
+
os.makedirs(folder_path)
|
|
475
|
+
|
|
476
|
+
with pytest.raises(InvalidManifest, match=f'Folder "{folder_path}" is already defined in {yaml_file_1!s}'):
|
|
477
|
+
Manifest.from_files([str(yaml_file_1), str(yaml_file_2)])
|
|
478
|
+
|
|
479
|
+
monkeypatch.setattr(idf_build_apps.manifest.manifest.Manifest, 'CHECK_MANIFEST_RULES', False)
|
|
480
|
+
Manifest.from_files([str(yaml_file_1), str(yaml_file_2)])
|
|
481
|
+
|
|
482
|
+
def test_manifest_dump_sha(self, tmp_path, sha_of_enable_only_esp32):
|
|
483
|
+
yaml_file = tmp_path / 'test.yml'
|
|
484
|
+
yaml_file.write_text(
|
|
485
|
+
"""
|
|
486
|
+
foo:
|
|
487
|
+
enable:
|
|
488
|
+
- if: IDF_TARGET == "esp32"
|
|
489
|
+
bar:
|
|
490
|
+
enable:
|
|
491
|
+
- if: IDF_TARGET == "esp32"
|
|
492
|
+
""",
|
|
493
|
+
encoding='utf8',
|
|
494
|
+
)
|
|
495
|
+
|
|
496
|
+
Manifest.from_file(yaml_file).dump_sha_values(str(tmp_path / '.sha'))
|
|
497
|
+
|
|
498
|
+
with open('.sha') as f:
|
|
499
|
+
assert f.readline() == f'bar:{sha_of_enable_only_esp32}\n'
|
|
500
|
+
assert f.readline() == f'foo:{sha_of_enable_only_esp32}\n'
|
|
501
|
+
|
|
502
|
+
def test_manifest_diff_sha(self, tmp_path, sha_of_enable_only_esp32):
|
|
503
|
+
yaml_file = tmp_path / 'test.yml'
|
|
504
|
+
yaml_file.write_text(
|
|
505
|
+
"""
|
|
506
|
+
foo:
|
|
507
|
+
enable:
|
|
508
|
+
- if: IDF_TARGET == "esp32"
|
|
509
|
+
- if: IDF_TARGET == "esp32c3"
|
|
510
|
+
bar:
|
|
511
|
+
enable:
|
|
512
|
+
- if: IDF_TARGET == "esp32"
|
|
513
|
+
baz:
|
|
514
|
+
enable:
|
|
515
|
+
- if: IDF_TARGET == "esp32"
|
|
516
|
+
""",
|
|
517
|
+
encoding='utf8',
|
|
518
|
+
)
|
|
519
|
+
|
|
520
|
+
with open('.sha', 'w') as fw:
|
|
521
|
+
fw.write(f'bar:{sha_of_enable_only_esp32}\n')
|
|
522
|
+
fw.write('\n') # test empty line
|
|
523
|
+
fw.write(' ') # test spaces
|
|
524
|
+
fw.write(f'foo:{sha_of_enable_only_esp32}\n')
|
|
525
|
+
|
|
526
|
+
assert Manifest.from_file(yaml_file).diff_sha_with_filepath(str(tmp_path / '.sha')) == {
|
|
527
|
+
'baz',
|
|
528
|
+
'foo',
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
def test_folder_rule_introduced_by(self, tmp_path):
|
|
532
|
+
yaml_file = tmp_path / 'test.yml'
|
|
533
|
+
yaml_file.write_text(
|
|
534
|
+
"""
|
|
535
|
+
foo:
|
|
536
|
+
enable:
|
|
537
|
+
- if: IDF_TARGET == "esp32"
|
|
538
|
+
- if: IDF_TARGET == "esp32c3"
|
|
539
|
+
bar:
|
|
540
|
+
enable:
|
|
541
|
+
- if: IDF_TARGET == "esp32"
|
|
542
|
+
baz:
|
|
543
|
+
enable:
|
|
544
|
+
- if: IDF_TARGET == "esp32"
|
|
545
|
+
""",
|
|
546
|
+
encoding='utf8',
|
|
547
|
+
)
|
|
548
|
+
|
|
549
|
+
manifest = Manifest.from_file(yaml_file)
|
|
550
|
+
assert manifest.most_suitable_rule('baz').by_manifest_file == str(yaml_file)
|
|
551
|
+
|
|
552
|
+
|
|
553
|
+
class TestIfParser:
|
|
554
|
+
def test_invalid_if_statement(self):
|
|
555
|
+
statement = '1'
|
|
556
|
+
with pytest.raises(InvalidIfClause, match='Invalid if clause: 1'):
|
|
557
|
+
IfClause(statement)
|
|
558
|
+
|
|
559
|
+
def test_temporary_must_with_reason(self):
|
|
560
|
+
with pytest.raises(InvalidIfClause, match='"reason" must be set when "temporary: true"'):
|
|
561
|
+
IfClause(stmt='IDF_TARGET == "esp32"', temporary=True)
|