idf-build-apps 2.5.3__py3-none-any.whl → 2.6.1__py3-none-any.whl
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/__init__.py +2 -2
- idf_build_apps/args.py +89 -65
- idf_build_apps/constants.py +11 -56
- idf_build_apps/finder.py +1 -0
- idf_build_apps/junit/utils.py +1 -1
- idf_build_apps/main.py +7 -5
- idf_build_apps/manifest/__init__.py +12 -1
- idf_build_apps/manifest/manifest.py +16 -8
- idf_build_apps/manifest/soc_header.py +3 -138
- idf_build_apps/py.typed +0 -0
- idf_build_apps/vendors/pydantic_sources.py +53 -34
- {idf_build_apps-2.5.3.dist-info → idf_build_apps-2.6.1.dist-info}/METADATA +5 -3
- idf_build_apps-2.6.1.dist-info/RECORD +27 -0
- {idf_build_apps-2.5.3.dist-info → idf_build_apps-2.6.1.dist-info}/WHEEL +1 -1
- idf_build_apps/manifest/if_parser.py +0 -240
- idf_build_apps-2.5.3.dist-info/RECORD +0 -27
- {idf_build_apps-2.5.3.dist-info → idf_build_apps-2.6.1.dist-info}/LICENSE +0 -0
- {idf_build_apps-2.5.3.dist-info → idf_build_apps-2.6.1.dist-info}/entry_points.txt +0 -0
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
# SPDX-FileCopyrightText: 2022-
|
|
1
|
+
# SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
|
2
2
|
# SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
import logging
|
|
4
4
|
import os
|
|
5
|
-
import pickle
|
|
6
5
|
import typing as t
|
|
7
6
|
from hashlib import sha512
|
|
8
7
|
|
|
8
|
+
from esp_bool_parser import BoolStmt, parse_bool_expr
|
|
9
9
|
from pyparsing import (
|
|
10
10
|
ParseException,
|
|
11
11
|
)
|
|
@@ -23,10 +23,6 @@ from ..utils import (
|
|
|
23
23
|
from ..yaml import (
|
|
24
24
|
parse,
|
|
25
25
|
)
|
|
26
|
-
from .if_parser import (
|
|
27
|
-
BOOL_EXPR,
|
|
28
|
-
BoolStmt,
|
|
29
|
-
)
|
|
30
26
|
|
|
31
27
|
LOGGER = logging.getLogger(__name__)
|
|
32
28
|
|
|
@@ -34,7 +30,8 @@ LOGGER = logging.getLogger(__name__)
|
|
|
34
30
|
class IfClause:
|
|
35
31
|
def __init__(self, stmt: str, temporary: bool = False, reason: t.Optional[str] = None) -> None:
|
|
36
32
|
try:
|
|
37
|
-
self.stmt: BoolStmt =
|
|
33
|
+
self.stmt: BoolStmt = parse_bool_expr(stmt)
|
|
34
|
+
self._stmt: str = stmt
|
|
38
35
|
except (ParseException, InvalidIfClause) as ex:
|
|
39
36
|
raise InvalidIfClause(f'Invalid if clause: {stmt}. {ex}')
|
|
40
37
|
|
|
@@ -51,6 +48,9 @@ class IfClause:
|
|
|
51
48
|
f' reason: lack of ci runners'
|
|
52
49
|
)
|
|
53
50
|
|
|
51
|
+
def __repr__(self):
|
|
52
|
+
return f'IfClause(stmt={self._stmt!r}, temporary={self.temporary!r}, reason={self.reason!r})'
|
|
53
|
+
|
|
54
54
|
def get_value(self, target: str, config_name: str) -> t.Any:
|
|
55
55
|
return self.stmt.get_value(target, config_name)
|
|
56
56
|
|
|
@@ -69,6 +69,14 @@ class SwitchClause:
|
|
|
69
69
|
return content
|
|
70
70
|
return self.default_clause
|
|
71
71
|
|
|
72
|
+
def __repr__(self) -> str:
|
|
73
|
+
return (
|
|
74
|
+
f'SwitchClause('
|
|
75
|
+
f'if_clauses={self.if_clauses!r}, '
|
|
76
|
+
f'contents={self.contents!r}, '
|
|
77
|
+
f'default_clause={self.default_clause!r})'
|
|
78
|
+
)
|
|
79
|
+
|
|
72
80
|
|
|
73
81
|
class FolderRule:
|
|
74
82
|
DEFAULT_BUILD_TARGETS = SUPPORTED_TARGETS
|
|
@@ -153,7 +161,7 @@ class FolderRule:
|
|
|
153
161
|
self.depends_components,
|
|
154
162
|
self.depends_filepatterns,
|
|
155
163
|
]:
|
|
156
|
-
sha.update(
|
|
164
|
+
sha.update(repr(obj).encode())
|
|
157
165
|
|
|
158
166
|
return sha.hexdigest()
|
|
159
167
|
|
|
@@ -1,141 +1,6 @@
|
|
|
1
|
-
# SPDX-FileCopyrightText:
|
|
1
|
+
# SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
|
2
2
|
# SPDX-License-Identifier: Apache-2.0
|
|
3
|
-
import logging
|
|
4
|
-
import os.path
|
|
5
|
-
import typing as t
|
|
6
|
-
from pathlib import (
|
|
7
|
-
Path,
|
|
8
|
-
)
|
|
9
3
|
|
|
10
|
-
|
|
11
|
-
CaselessLiteral,
|
|
12
|
-
Char,
|
|
13
|
-
Combine,
|
|
14
|
-
Group,
|
|
15
|
-
Literal,
|
|
16
|
-
MatchFirst,
|
|
17
|
-
OneOrMore,
|
|
18
|
-
Optional,
|
|
19
|
-
ParseException,
|
|
20
|
-
ParseResults,
|
|
21
|
-
QuotedString,
|
|
22
|
-
Word,
|
|
23
|
-
alphas,
|
|
24
|
-
hexnums,
|
|
25
|
-
nums,
|
|
26
|
-
)
|
|
4
|
+
import esp_bool_parser
|
|
27
5
|
|
|
28
|
-
|
|
29
|
-
ALL_TARGETS,
|
|
30
|
-
IDF_PATH,
|
|
31
|
-
)
|
|
32
|
-
|
|
33
|
-
LOGGER = logging.getLogger(__name__)
|
|
34
|
-
|
|
35
|
-
# Group for parsing literal suffix of a numbers, e.g. 100UL
|
|
36
|
-
_literal_symbol = Group(CaselessLiteral('L') | CaselessLiteral('U'))
|
|
37
|
-
_literal_suffix = OneOrMore(_literal_symbol)
|
|
38
|
-
|
|
39
|
-
# Define name
|
|
40
|
-
_name = Word(alphas, alphas + nums + '_')
|
|
41
|
-
|
|
42
|
-
# Define value, either a hex, int or a string
|
|
43
|
-
_hex_value = Combine(Literal('0x') + Word(hexnums) + Optional(_literal_suffix).suppress())('hex_value')
|
|
44
|
-
_str_value = QuotedString('"')('str_value')
|
|
45
|
-
_int_value = Word(nums)('int_value') + ~Char('.') + Optional(_literal_suffix)('literal_suffix')
|
|
46
|
-
|
|
47
|
-
# Remove optional parenthesis around values
|
|
48
|
-
_value = Optional('(').suppress() + MatchFirst([_hex_value, _str_value, _int_value])('value') + Optional(')').suppress()
|
|
49
|
-
|
|
50
|
-
_define_expr = '#define' + Optional(_name)('name') + Optional(_value)
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
def get_defines(header_path: str) -> t.List[str]:
|
|
54
|
-
defines = []
|
|
55
|
-
LOGGER.debug('Reading macros from %s...', header_path)
|
|
56
|
-
with open(header_path) as f:
|
|
57
|
-
output = f.read()
|
|
58
|
-
|
|
59
|
-
for line in output.split('\n'):
|
|
60
|
-
line = line.strip()
|
|
61
|
-
if len(line):
|
|
62
|
-
defines.append(line)
|
|
63
|
-
|
|
64
|
-
return defines
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
def parse_define(define_line: str) -> ParseResults:
|
|
68
|
-
res = _define_expr.parseString(define_line)
|
|
69
|
-
|
|
70
|
-
return res
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
class SocHeader(dict):
|
|
74
|
-
CAPS_HEADER_FILEPATTERN = '*_caps.h'
|
|
75
|
-
|
|
76
|
-
def __init__(self, target: str) -> None:
|
|
77
|
-
if target != 'linux':
|
|
78
|
-
soc_header_dict = self._parse_soc_header(target)
|
|
79
|
-
else:
|
|
80
|
-
soc_header_dict = {}
|
|
81
|
-
|
|
82
|
-
super().__init__(**soc_header_dict)
|
|
83
|
-
|
|
84
|
-
@staticmethod
|
|
85
|
-
def _get_dirs_from_candidates(candidates: t.List[str]) -> t.List[str]:
|
|
86
|
-
dirs = []
|
|
87
|
-
for d in candidates:
|
|
88
|
-
if not os.path.isdir(d):
|
|
89
|
-
LOGGER.debug('folder "%s" not found. Skipping...', os.path.abspath(d))
|
|
90
|
-
else:
|
|
91
|
-
dirs.append(d)
|
|
92
|
-
|
|
93
|
-
return dirs
|
|
94
|
-
|
|
95
|
-
@classmethod
|
|
96
|
-
def _parse_soc_header(cls, target: str) -> t.Dict[str, t.Any]:
|
|
97
|
-
soc_headers_dirs = cls._get_dirs_from_candidates(
|
|
98
|
-
[
|
|
99
|
-
# master c5 mp
|
|
100
|
-
os.path.abspath(os.path.join(IDF_PATH, 'components', 'soc', target, 'mp', 'include', 'soc')),
|
|
101
|
-
# other branches
|
|
102
|
-
os.path.abspath(os.path.join(IDF_PATH, 'components', 'soc', target, 'include', 'soc')),
|
|
103
|
-
# release/v4.2
|
|
104
|
-
os.path.abspath(os.path.join(IDF_PATH, 'components', 'soc', 'soc', target, 'include', 'soc')),
|
|
105
|
-
]
|
|
106
|
-
)
|
|
107
|
-
esp_rom_headers_dirs = cls._get_dirs_from_candidates(
|
|
108
|
-
[
|
|
109
|
-
# master c5 mp
|
|
110
|
-
os.path.abspath(os.path.join(IDF_PATH, 'components', 'esp_rom', target, 'mp', target)),
|
|
111
|
-
# others
|
|
112
|
-
os.path.abspath(os.path.join(IDF_PATH, 'components', 'esp_rom', target)),
|
|
113
|
-
]
|
|
114
|
-
)
|
|
115
|
-
|
|
116
|
-
header_files: t.List[str] = []
|
|
117
|
-
for d in [*soc_headers_dirs, *esp_rom_headers_dirs]:
|
|
118
|
-
LOGGER.debug('Checking dir %s', d)
|
|
119
|
-
header_files += [str(p.resolve()) for p in Path(d).glob(cls.CAPS_HEADER_FILEPATTERN)]
|
|
120
|
-
|
|
121
|
-
output_dict = {}
|
|
122
|
-
for f in header_files:
|
|
123
|
-
LOGGER.debug('Checking header file %s', f)
|
|
124
|
-
for line in get_defines(f):
|
|
125
|
-
try:
|
|
126
|
-
res = parse_define(line)
|
|
127
|
-
except ParseException:
|
|
128
|
-
LOGGER.debug('Failed to parse: %s', line)
|
|
129
|
-
continue
|
|
130
|
-
|
|
131
|
-
if 'str_value' in res:
|
|
132
|
-
output_dict[res.name] = res.str_value
|
|
133
|
-
elif 'int_value' in res:
|
|
134
|
-
output_dict[res.name] = int(res.int_value)
|
|
135
|
-
elif 'hex_value' in res:
|
|
136
|
-
output_dict[res.name] = int(res.hex_value, 16)
|
|
137
|
-
|
|
138
|
-
return output_dict
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
SOC_HEADERS: t.Dict[str, SocHeader] = {target: SocHeader(target) for target in ALL_TARGETS}
|
|
6
|
+
SOC_HEADERS = esp_bool_parser.SOC_HEADERS
|
idf_build_apps/py.typed
ADDED
|
File without changes
|
|
@@ -14,6 +14,7 @@ Modifications:
|
|
|
14
14
|
- use toml instead of tomli when python < 3.11
|
|
15
15
|
- stop using global variables
|
|
16
16
|
- fix some warnings
|
|
17
|
+
- recursively find TOML file.
|
|
17
18
|
"""
|
|
18
19
|
|
|
19
20
|
import os
|
|
@@ -25,8 +26,10 @@ from typing import Any, Dict, List, Optional, Tuple, Type, Union
|
|
|
25
26
|
from pydantic_settings import InitSettingsSource
|
|
26
27
|
from pydantic_settings.main import BaseSettings
|
|
27
28
|
|
|
29
|
+
from idf_build_apps.constants import IDF_BUILD_APPS_TOML_FN
|
|
30
|
+
|
|
28
31
|
PathType = Union[Path, str, List[Union[Path, str]], Tuple[Union[Path, str], ...]]
|
|
29
|
-
DEFAULT_PATH
|
|
32
|
+
DEFAULT_PATH = Path('')
|
|
30
33
|
|
|
31
34
|
|
|
32
35
|
class ConfigFileSourceMixin(ABC):
|
|
@@ -43,7 +46,7 @@ class ConfigFileSourceMixin(ABC):
|
|
|
43
46
|
return kwargs
|
|
44
47
|
|
|
45
48
|
@abstractmethod
|
|
46
|
-
def _read_file(self, path: Path) -> Dict[str, Any]:
|
|
49
|
+
def _read_file(self, path: Optional[Path]) -> Dict[str, Any]:
|
|
47
50
|
pass
|
|
48
51
|
|
|
49
52
|
|
|
@@ -55,24 +58,61 @@ class TomlConfigSettingsSource(InitSettingsSource, ConfigFileSourceMixin):
|
|
|
55
58
|
def __init__(
|
|
56
59
|
self,
|
|
57
60
|
settings_cls: Type[BaseSettings],
|
|
58
|
-
toml_file: Optional[
|
|
61
|
+
toml_file: Optional[Path] = DEFAULT_PATH,
|
|
59
62
|
):
|
|
60
|
-
self.toml_file_path =
|
|
63
|
+
self.toml_file_path = self._pick_toml_file(
|
|
64
|
+
toml_file,
|
|
65
|
+
settings_cls.model_config.get('pyproject_toml_depth', sys.maxsize),
|
|
66
|
+
IDF_BUILD_APPS_TOML_FN,
|
|
67
|
+
)
|
|
61
68
|
self.toml_data = self._read_files(self.toml_file_path)
|
|
62
69
|
super().__init__(settings_cls, self.toml_data)
|
|
63
70
|
|
|
64
|
-
def _read_file(self,
|
|
71
|
+
def _read_file(self, path: Optional[Path]) -> Dict[str, Any]:
|
|
72
|
+
if not path or not path.is_file():
|
|
73
|
+
return {}
|
|
74
|
+
|
|
65
75
|
if sys.version_info < (3, 11):
|
|
66
76
|
import toml
|
|
67
77
|
|
|
68
|
-
with open(
|
|
78
|
+
with open(path) as toml_file:
|
|
69
79
|
return toml.load(toml_file)
|
|
70
80
|
else:
|
|
71
81
|
import tomllib
|
|
72
82
|
|
|
73
|
-
with open(
|
|
83
|
+
with open(path, 'rb') as toml_file:
|
|
74
84
|
return tomllib.load(toml_file)
|
|
75
85
|
|
|
86
|
+
@staticmethod
|
|
87
|
+
def _pick_toml_file(provided: Optional[Path], depth: int, filename: str) -> Optional[Path]:
|
|
88
|
+
"""
|
|
89
|
+
Pick a file path to use. If a file path is provided, use it. Otherwise, search up the directory tree for a
|
|
90
|
+
file with the given name.
|
|
91
|
+
|
|
92
|
+
:param provided: Explicit path provided when instantiating this class.
|
|
93
|
+
:param depth: Number of directories up the tree to check of a pyproject.toml.
|
|
94
|
+
"""
|
|
95
|
+
if provided and Path(provided).is_file():
|
|
96
|
+
fp = provided.resolve()
|
|
97
|
+
print(f'Loading config file: {fp}')
|
|
98
|
+
return fp
|
|
99
|
+
|
|
100
|
+
rv = Path.cwd()
|
|
101
|
+
count = -1
|
|
102
|
+
while count < depth:
|
|
103
|
+
if str(rv) == rv.root:
|
|
104
|
+
break
|
|
105
|
+
|
|
106
|
+
fp = rv / filename
|
|
107
|
+
if fp.is_file():
|
|
108
|
+
print(f'Loading config file: {fp}')
|
|
109
|
+
return fp
|
|
110
|
+
|
|
111
|
+
rv = rv.parent
|
|
112
|
+
count += 1
|
|
113
|
+
|
|
114
|
+
return None
|
|
115
|
+
|
|
76
116
|
|
|
77
117
|
class PyprojectTomlConfigSettingsSource(TomlConfigSettingsSource):
|
|
78
118
|
"""
|
|
@@ -84,37 +124,16 @@ class PyprojectTomlConfigSettingsSource(TomlConfigSettingsSource):
|
|
|
84
124
|
settings_cls: Type[BaseSettings],
|
|
85
125
|
toml_file: Optional[Path] = None,
|
|
86
126
|
) -> None:
|
|
87
|
-
self.toml_file_path = self.
|
|
88
|
-
toml_file,
|
|
127
|
+
self.toml_file_path = self._pick_toml_file(
|
|
128
|
+
toml_file,
|
|
129
|
+
settings_cls.model_config.get('pyproject_toml_depth', sys.maxsize),
|
|
130
|
+
'pyproject.toml',
|
|
89
131
|
)
|
|
90
132
|
self.toml_table_header: Tuple[str, ...] = settings_cls.model_config.get(
|
|
91
|
-
'pyproject_toml_table_header',
|
|
133
|
+
'pyproject_toml_table_header',
|
|
134
|
+
('tool', 'idf-build-apps'),
|
|
92
135
|
)
|
|
93
136
|
self.toml_data = self._read_files(self.toml_file_path)
|
|
94
137
|
for key in self.toml_table_header:
|
|
95
138
|
self.toml_data = self.toml_data.get(key, {})
|
|
96
139
|
super(TomlConfigSettingsSource, self).__init__(settings_cls, self.toml_data)
|
|
97
|
-
|
|
98
|
-
@staticmethod
|
|
99
|
-
def _pick_pyproject_toml_file(provided: Optional[Path], depth: int) -> Path:
|
|
100
|
-
"""Pick a `pyproject.toml` file path to use.
|
|
101
|
-
|
|
102
|
-
Args:
|
|
103
|
-
provided: Explicit path provided when instantiating this class.
|
|
104
|
-
depth: Number of directories up the tree to check of a pyproject.toml.
|
|
105
|
-
|
|
106
|
-
"""
|
|
107
|
-
if provided:
|
|
108
|
-
return provided.resolve()
|
|
109
|
-
rv = Path.cwd() / 'pyproject.toml'
|
|
110
|
-
count = 0
|
|
111
|
-
if not rv.is_file():
|
|
112
|
-
child = rv.parent.parent / 'pyproject.toml'
|
|
113
|
-
while count < depth:
|
|
114
|
-
if child.is_file():
|
|
115
|
-
return child
|
|
116
|
-
if str(child.parent) == rv.root:
|
|
117
|
-
break # end discovery after checking system root once
|
|
118
|
-
child = child.parent.parent / 'pyproject.toml'
|
|
119
|
-
count += 1
|
|
120
|
-
return rv
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
2
|
Name: idf-build-apps
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.6.1
|
|
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
|
|
@@ -21,15 +21,17 @@ Requires-Dist: pydantic~=2.0
|
|
|
21
21
|
Requires-Dist: pydantic_settings
|
|
22
22
|
Requires-Dist: argcomplete>=3
|
|
23
23
|
Requires-Dist: typing-extensions; python_version < '3.11'
|
|
24
|
+
Requires-Dist: esp-bool-parser>=0.1.2,<1
|
|
24
25
|
Requires-Dist: sphinx ; extra == "doc"
|
|
25
26
|
Requires-Dist: sphinx-rtd-theme ; extra == "doc"
|
|
26
27
|
Requires-Dist: sphinx_copybutton ; extra == "doc"
|
|
27
28
|
Requires-Dist: myst-parser ; extra == "doc"
|
|
28
29
|
Requires-Dist: sphinxcontrib-mermaid ; extra == "doc"
|
|
29
30
|
Requires-Dist: sphinx-argparse ; extra == "doc"
|
|
31
|
+
Requires-Dist: sphinx-tabs ; extra == "doc"
|
|
30
32
|
Requires-Dist: pytest ; extra == "test"
|
|
31
33
|
Requires-Dist: pytest-cov ; extra == "test"
|
|
32
|
-
Project-URL: changelog, https://github.com/espressif/idf-build-apps/blob/
|
|
34
|
+
Project-URL: changelog, https://github.com/espressif/idf-build-apps/blob/main/CHANGELOG.md
|
|
33
35
|
Project-URL: documentation, https://docs.espressif.com/projects/idf-build-apps
|
|
34
36
|
Project-URL: homepage, https://github.com/espressif/idf-build-apps
|
|
35
37
|
Project-URL: repository, https://github.com/espressif/idf-build-apps
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
idf_build_apps/__init__.py,sha256=vUpvuUfhUex6RVt7a3vpSTczJJkHz8qSc2HqbwFW_80,650
|
|
2
|
+
idf_build_apps/__main__.py,sha256=8E-5xHm2MlRun0L88XJleNh5U50dpE0Q1nK5KqomA7I,182
|
|
3
|
+
idf_build_apps/app.py,sha256=F-MKOsaz7cJ0H2wsEE4gpO4kkkEdkyFmIZBHDoM2qgs,37359
|
|
4
|
+
idf_build_apps/args.py,sha256=zB08ctBXFz1UkPv4r7kE6E6sBezCFrrzt99HKRDiRTA,34821
|
|
5
|
+
idf_build_apps/autocompletions.py,sha256=g-bx0pzXoFKI0VQqftkHyGVWN6MLjuFOdozeuAf45yo,2138
|
|
6
|
+
idf_build_apps/constants.py,sha256=HU0rtKqhvLj9nMsy6XvyQMjMEBliNi9xaS2D8CQEPsE,2421
|
|
7
|
+
idf_build_apps/finder.py,sha256=hY6uSMB2s65MqMKIDBSHABOfa93mOLT7x5hlMxC43EQ,5794
|
|
8
|
+
idf_build_apps/log.py,sha256=pyvT7N4MWzGjIXph5mThQCGBiSt53RNPW0WrFfLr0Kw,2650
|
|
9
|
+
idf_build_apps/main.py,sha256=SZauvC_DNEsl1Twc5xQxHSSPt8sgYsNOZjN4UjHk0gQ,16569
|
|
10
|
+
idf_build_apps/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
11
|
+
idf_build_apps/session_args.py,sha256=2WDTy40IFAc0KQ57HaeBcYj_k10eUXRKkDOWLrFCaHY,2985
|
|
12
|
+
idf_build_apps/utils.py,sha256=s4D8P7QA17XcaCUQ_EoiNOW_VpU3cPQgiZVV9KQ8I30,10171
|
|
13
|
+
idf_build_apps/junit/__init__.py,sha256=IxvdaS6eSXp7kZxRuXqyZyGxuA_A1nOW1jF1HMi8Gns,231
|
|
14
|
+
idf_build_apps/junit/report.py,sha256=T7dVU3Sz5tqjfbcFW7wjsb65PDH6C2HFf73ePJqBhMs,6555
|
|
15
|
+
idf_build_apps/junit/utils.py,sha256=NXZxQD4tdbSVKjKMNx1kO2H3IoEiysXkDoDjLEf1RO8,1303
|
|
16
|
+
idf_build_apps/manifest/__init__.py,sha256=LYGR9doEKGPEdsJPuHnmJmV-qw2kuAipV0bodkhY_JE,399
|
|
17
|
+
idf_build_apps/manifest/manifest.py,sha256=5BIzNzGAk0w5qOCTMGsmvKcN4DQLwUi6JVGt2G4JKQs,14793
|
|
18
|
+
idf_build_apps/manifest/soc_header.py,sha256=_F6H5-HP6ateAqKUGlRGH-SUtQ8NJ1RI0hBeCFvsDYA,172
|
|
19
|
+
idf_build_apps/vendors/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
20
|
+
idf_build_apps/vendors/pydantic_sources.py,sha256=cO316vq4wAw51O1-KsYz8jrhiI_lkCghiPCYyH0Ghik,4487
|
|
21
|
+
idf_build_apps/yaml/__init__.py,sha256=W-3z5no07RQ6eYKGyOAPA8Z2CLiMPob8DD91I4URjrA,162
|
|
22
|
+
idf_build_apps/yaml/parser.py,sha256=b3LvogO6do-eJPRsYzT-8xk8AT2MnXpLCzQutJqyC7M,2128
|
|
23
|
+
idf_build_apps-2.6.1.dist-info/entry_points.txt,sha256=3pVUirUEsb6jsDRikkQWNUt4hqLK2ci1HvW_Vf8b6uE,59
|
|
24
|
+
idf_build_apps-2.6.1.dist-info/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
|
|
25
|
+
idf_build_apps-2.6.1.dist-info/WHEEL,sha256=CpUCUxeHQbRN5UGRQHYRJorO5Af-Qy_fHMctcQ8DSGI,82
|
|
26
|
+
idf_build_apps-2.6.1.dist-info/METADATA,sha256=z7cnY1oC-PXymCxVYo7_Ao5LvPnFyzblDYVE_sUavbI,4693
|
|
27
|
+
idf_build_apps-2.6.1.dist-info/RECORD,,
|
|
@@ -1,240 +0,0 @@
|
|
|
1
|
-
# SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
|
2
|
-
# SPDX-License-Identifier: Apache-2.0
|
|
3
|
-
import operator
|
|
4
|
-
import os
|
|
5
|
-
from ast import (
|
|
6
|
-
literal_eval,
|
|
7
|
-
)
|
|
8
|
-
from typing import (
|
|
9
|
-
Any,
|
|
10
|
-
)
|
|
11
|
-
|
|
12
|
-
from packaging.version import (
|
|
13
|
-
Version,
|
|
14
|
-
)
|
|
15
|
-
from pyparsing import (
|
|
16
|
-
Keyword,
|
|
17
|
-
Literal,
|
|
18
|
-
MatchFirst,
|
|
19
|
-
ParseResults,
|
|
20
|
-
QuotedString,
|
|
21
|
-
Suppress,
|
|
22
|
-
Word,
|
|
23
|
-
alphas,
|
|
24
|
-
delimitedList,
|
|
25
|
-
hexnums,
|
|
26
|
-
infixNotation,
|
|
27
|
-
nums,
|
|
28
|
-
opAssoc,
|
|
29
|
-
)
|
|
30
|
-
|
|
31
|
-
from ..constants import (
|
|
32
|
-
IDF_VERSION,
|
|
33
|
-
IDF_VERSION_MAJOR,
|
|
34
|
-
IDF_VERSION_MINOR,
|
|
35
|
-
IDF_VERSION_PATCH,
|
|
36
|
-
)
|
|
37
|
-
from ..utils import (
|
|
38
|
-
InvalidIfClause,
|
|
39
|
-
InvalidInput,
|
|
40
|
-
to_version,
|
|
41
|
-
)
|
|
42
|
-
from .soc_header import (
|
|
43
|
-
SOC_HEADERS,
|
|
44
|
-
)
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
class Stmt:
|
|
48
|
-
"""
|
|
49
|
-
Statement
|
|
50
|
-
"""
|
|
51
|
-
|
|
52
|
-
def get_value(self, target: str, config_name: str) -> Any:
|
|
53
|
-
"""
|
|
54
|
-
Lazy calculated. All subclasses of `Stmt` should implement this function.
|
|
55
|
-
|
|
56
|
-
:param target: ESP-IDF target
|
|
57
|
-
:type target: str
|
|
58
|
-
:param config_name: config name
|
|
59
|
-
:type target: str
|
|
60
|
-
:return: the value of the statement
|
|
61
|
-
"""
|
|
62
|
-
raise NotImplementedError('Please implement this function in sub classes')
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
class ChipAttr(Stmt):
|
|
66
|
-
"""
|
|
67
|
-
Attributes defined in SOC Header Files and other keywords as followed:
|
|
68
|
-
|
|
69
|
-
- IDF_TARGET: target
|
|
70
|
-
- INCLUDE_DEFAULT: take the default build targets into account or not
|
|
71
|
-
- IDF_VERSION_MAJOR: major version of ESP-IDF
|
|
72
|
-
- IDF_VERSION_MINOR: minor version of ESP-IDF
|
|
73
|
-
- IDF_VERSION_PATCH: patch version of ESP-IDF
|
|
74
|
-
- CONFIG_NAME: config name defined in the config rules
|
|
75
|
-
"""
|
|
76
|
-
|
|
77
|
-
def __init__(self, t: ParseResults):
|
|
78
|
-
self.attr: str = t[0]
|
|
79
|
-
|
|
80
|
-
def get_value(self, target: str, config_name: str) -> Any:
|
|
81
|
-
from .manifest import FolderRule # lazy-load
|
|
82
|
-
|
|
83
|
-
if self.attr == 'IDF_TARGET':
|
|
84
|
-
return target
|
|
85
|
-
|
|
86
|
-
if self.attr == 'INCLUDE_DEFAULT':
|
|
87
|
-
return 1 if target in FolderRule.DEFAULT_BUILD_TARGETS else 0
|
|
88
|
-
|
|
89
|
-
if self.attr == 'IDF_VERSION':
|
|
90
|
-
return IDF_VERSION
|
|
91
|
-
|
|
92
|
-
if self.attr == 'IDF_VERSION_MAJOR':
|
|
93
|
-
return IDF_VERSION_MAJOR
|
|
94
|
-
|
|
95
|
-
if self.attr == 'IDF_VERSION_MINOR':
|
|
96
|
-
return IDF_VERSION_MINOR
|
|
97
|
-
|
|
98
|
-
if self.attr == 'IDF_VERSION_PATCH':
|
|
99
|
-
return IDF_VERSION_PATCH
|
|
100
|
-
|
|
101
|
-
if self.attr == 'CONFIG_NAME':
|
|
102
|
-
return config_name
|
|
103
|
-
|
|
104
|
-
if self.attr in SOC_HEADERS[target]:
|
|
105
|
-
return SOC_HEADERS[target][self.attr]
|
|
106
|
-
|
|
107
|
-
# for non-keyword cap words, check if it is defined in the environment variables
|
|
108
|
-
if self.attr in os.environ:
|
|
109
|
-
return os.environ[self.attr]
|
|
110
|
-
|
|
111
|
-
return 0 # default return 0 as false
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
class Integer(Stmt):
|
|
115
|
-
def __init__(self, t: ParseResults):
|
|
116
|
-
self.expr: str = t[0]
|
|
117
|
-
|
|
118
|
-
def get_value(self, target: str, config_name: str) -> Any: # noqa: ARG002
|
|
119
|
-
return literal_eval(self.expr)
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
class String(Stmt):
|
|
123
|
-
def __init__(self, t: ParseResults):
|
|
124
|
-
self.expr: str = t[0]
|
|
125
|
-
|
|
126
|
-
def get_value(self, target: str, config_name: str) -> Any: # noqa: ARG002
|
|
127
|
-
return literal_eval(f'"{self.expr}"') # double quotes is swallowed by QuotedString
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
class List_(Stmt):
|
|
131
|
-
def __init__(self, t: ParseResults):
|
|
132
|
-
self.expr = t
|
|
133
|
-
|
|
134
|
-
def get_value(self, target: str, config_name: str) -> Any:
|
|
135
|
-
return [item.get_value(target, config_name) for item in self.expr]
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
class BoolStmt(Stmt):
|
|
139
|
-
_OP_DICT = {
|
|
140
|
-
'==': operator.eq,
|
|
141
|
-
'!=': operator.ne,
|
|
142
|
-
'>': operator.gt,
|
|
143
|
-
'>=': operator.ge,
|
|
144
|
-
'<': operator.lt,
|
|
145
|
-
'<=': operator.le,
|
|
146
|
-
'not in': lambda x, y: x not in y,
|
|
147
|
-
'in': lambda x, y: x in y,
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
def __init__(self, t: ParseResults):
|
|
151
|
-
self.left: Stmt = t[0]
|
|
152
|
-
self.comparison: str = t[1]
|
|
153
|
-
self.right: Stmt = t[2]
|
|
154
|
-
|
|
155
|
-
def get_value(self, target: str, config_name: str) -> Any:
|
|
156
|
-
_l = self.left.get_value(target, config_name)
|
|
157
|
-
_r = self.right.get_value(target, config_name)
|
|
158
|
-
|
|
159
|
-
if self.comparison not in ['in', 'not in']:
|
|
160
|
-
# will use version comparison if any of the operands is a Version
|
|
161
|
-
if any(isinstance(x, Version) for x in [_l, _r]):
|
|
162
|
-
_l = to_version(_l)
|
|
163
|
-
_r = to_version(_r)
|
|
164
|
-
else:
|
|
165
|
-
# use str for "in" and "not in" operator
|
|
166
|
-
if isinstance(_l, Version):
|
|
167
|
-
_l = str(_l)
|
|
168
|
-
if isinstance(_r, Version):
|
|
169
|
-
_r = str(_r)
|
|
170
|
-
|
|
171
|
-
if self.comparison in self._OP_DICT:
|
|
172
|
-
return self._OP_DICT[self.comparison](_l, _r)
|
|
173
|
-
|
|
174
|
-
raise InvalidInput(f'Unsupported comparison operator: "{self.comparison}"')
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
class BoolExpr(Stmt):
|
|
178
|
-
pass
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
def _and(_l, _r):
|
|
182
|
-
return _l and _r
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
def _or(_l, _r):
|
|
186
|
-
return _l or _r
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
class BoolOrAnd(BoolExpr):
|
|
190
|
-
def __init__(self, t: ParseResults):
|
|
191
|
-
if len(t[0]) > 3:
|
|
192
|
-
raise InvalidIfClause(
|
|
193
|
-
'Chaining "and"/"or" is not allowed. Please use paratheses instead. '
|
|
194
|
-
'For example: "a and b and c" should be "(a and b) and c".'
|
|
195
|
-
)
|
|
196
|
-
self.left: BoolStmt = t[0][0]
|
|
197
|
-
self.right: BoolStmt = t[0][2]
|
|
198
|
-
|
|
199
|
-
if t[0][1] == 'and':
|
|
200
|
-
self.operation = _and
|
|
201
|
-
if t[0][1] == 'or':
|
|
202
|
-
self.operation = _or
|
|
203
|
-
|
|
204
|
-
def get_value(self, target: str, config_name: str) -> Any:
|
|
205
|
-
return self.operation(self.left.get_value(target, config_name), self.right.get_value(target, config_name))
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
CAP_WORD = Word(alphas.upper(), nums + alphas.upper() + '_').setParseAction(ChipAttr)
|
|
209
|
-
|
|
210
|
-
DECIMAL_NUMBER = Word(nums)
|
|
211
|
-
HEX_NUMBER = Literal('0x') + Word(hexnums)
|
|
212
|
-
INTEGER = (HEX_NUMBER | DECIMAL_NUMBER).setParseAction(Integer)
|
|
213
|
-
|
|
214
|
-
STRING = QuotedString('"').setParseAction(String)
|
|
215
|
-
|
|
216
|
-
LIST = Suppress('[') + delimitedList(INTEGER | STRING).setParseAction(List_) + Suppress(']')
|
|
217
|
-
|
|
218
|
-
BOOL_OPERAND = CAP_WORD | INTEGER | STRING | LIST
|
|
219
|
-
|
|
220
|
-
EQ = Keyword('==').setParseAction(lambda t: t[0])
|
|
221
|
-
NE = Keyword('!=').setParseAction(lambda t: t[0])
|
|
222
|
-
LE = Keyword('<=').setParseAction(lambda t: t[0])
|
|
223
|
-
LT = Keyword('<').setParseAction(lambda t: t[0])
|
|
224
|
-
GE = Keyword('>=').setParseAction(lambda t: t[0])
|
|
225
|
-
GT = Keyword('>').setParseAction(lambda t: t[0])
|
|
226
|
-
NOT_IN = Keyword('not in').setParseAction(lambda t: t[0])
|
|
227
|
-
IN = Keyword('in').setParseAction(lambda t: t[0])
|
|
228
|
-
|
|
229
|
-
BOOL_STMT = BOOL_OPERAND + (EQ | NE | LE | LT | GE | GT | NOT_IN | IN) + BOOL_OPERAND
|
|
230
|
-
BOOL_STMT.setParseAction(BoolStmt)
|
|
231
|
-
|
|
232
|
-
AND = Keyword('and')
|
|
233
|
-
OR = Keyword('or')
|
|
234
|
-
|
|
235
|
-
BOOL_EXPR = infixNotation(
|
|
236
|
-
BOOL_STMT,
|
|
237
|
-
[
|
|
238
|
-
(MatchFirst((AND, OR)), 2, opAssoc.LEFT, BoolOrAnd),
|
|
239
|
-
],
|
|
240
|
-
)
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
idf_build_apps/__init__.py,sha256=NC4Y3XHI515eQBX8WScygPjZaCgogb4zOZjjg_UEyaY,650
|
|
2
|
-
idf_build_apps/__main__.py,sha256=8E-5xHm2MlRun0L88XJleNh5U50dpE0Q1nK5KqomA7I,182
|
|
3
|
-
idf_build_apps/app.py,sha256=F-MKOsaz7cJ0H2wsEE4gpO4kkkEdkyFmIZBHDoM2qgs,37359
|
|
4
|
-
idf_build_apps/args.py,sha256=3lSzUZIkfJzzmhCJ8GICtKQQ1iY-dDotIOmmqwwUrF8,32762
|
|
5
|
-
idf_build_apps/autocompletions.py,sha256=g-bx0pzXoFKI0VQqftkHyGVWN6MLjuFOdozeuAf45yo,2138
|
|
6
|
-
idf_build_apps/constants.py,sha256=07ve2FtWuLBuc_6LFzbs1XncB1VNi9HJUqGjQQauRNM,3952
|
|
7
|
-
idf_build_apps/finder.py,sha256=Wv0QYArXmVZZDslLxfPwGgt202s94112AlAHk0s3N1g,5710
|
|
8
|
-
idf_build_apps/log.py,sha256=pyvT7N4MWzGjIXph5mThQCGBiSt53RNPW0WrFfLr0Kw,2650
|
|
9
|
-
idf_build_apps/main.py,sha256=Z_hetbOavgCJZQPaP01_jx57fR1w0DefiFz0J2cCwp0,16498
|
|
10
|
-
idf_build_apps/session_args.py,sha256=2WDTy40IFAc0KQ57HaeBcYj_k10eUXRKkDOWLrFCaHY,2985
|
|
11
|
-
idf_build_apps/utils.py,sha256=s4D8P7QA17XcaCUQ_EoiNOW_VpU3cPQgiZVV9KQ8I30,10171
|
|
12
|
-
idf_build_apps/junit/__init__.py,sha256=IxvdaS6eSXp7kZxRuXqyZyGxuA_A1nOW1jF1HMi8Gns,231
|
|
13
|
-
idf_build_apps/junit/report.py,sha256=T7dVU3Sz5tqjfbcFW7wjsb65PDH6C2HFf73ePJqBhMs,6555
|
|
14
|
-
idf_build_apps/junit/utils.py,sha256=j0PYhFTZjXtTwkENdeL4bFJcX24ktf1CsOOVXz65yNo,1297
|
|
15
|
-
idf_build_apps/manifest/__init__.py,sha256=Q2-cb3ngNjnl6_zWhUfzZZB10f_-Rv2JYNck3Lk7UkQ,133
|
|
16
|
-
idf_build_apps/manifest/if_parser.py,sha256=AAEyYPgcBWL2ToCmcvhx3fl8ebYdC5-LMvvDkYtWn8o,6546
|
|
17
|
-
idf_build_apps/manifest/manifest.py,sha256=6F6Nt93eaoBOHlGHZtv2hHT8Zw0HmJf0d_MESlgye6M,14478
|
|
18
|
-
idf_build_apps/manifest/soc_header.py,sha256=PzJ37xFspt5f0AXWvAFNA_avHZA9fMXHBrwDYLi3qEI,4344
|
|
19
|
-
idf_build_apps/vendors/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
20
|
-
idf_build_apps/vendors/pydantic_sources.py,sha256=2IN6opo6qjCwaqhERFbgA4PtEwqKaTtEkccy5_fYAT0,4130
|
|
21
|
-
idf_build_apps/yaml/__init__.py,sha256=W-3z5no07RQ6eYKGyOAPA8Z2CLiMPob8DD91I4URjrA,162
|
|
22
|
-
idf_build_apps/yaml/parser.py,sha256=b3LvogO6do-eJPRsYzT-8xk8AT2MnXpLCzQutJqyC7M,2128
|
|
23
|
-
idf_build_apps-2.5.3.dist-info/entry_points.txt,sha256=3pVUirUEsb6jsDRikkQWNUt4hqLK2ci1HvW_Vf8b6uE,59
|
|
24
|
-
idf_build_apps-2.5.3.dist-info/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
|
|
25
|
-
idf_build_apps-2.5.3.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81
|
|
26
|
-
idf_build_apps-2.5.3.dist-info/METADATA,sha256=XZLgJfyaJgEl6rULmN0zIeG9quKVH9EhuigO1hnQOvk,4610
|
|
27
|
-
idf_build_apps-2.5.3.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|