idf-build-apps 2.10.0__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.0 → idf_build_apps-2.10.2}/.pre-commit-config.yaml +1 -1
- {idf_build_apps-2.10.0 → idf_build_apps-2.10.2}/CHANGELOG.md +13 -0
- {idf_build_apps-2.10.0 → idf_build_apps-2.10.2}/PKG-INFO +3 -2
- {idf_build_apps-2.10.0 → idf_build_apps-2.10.2}/idf_build_apps/__init__.py +3 -1
- {idf_build_apps-2.10.0 → idf_build_apps-2.10.2}/idf_build_apps/app.py +8 -0
- {idf_build_apps-2.10.0 → idf_build_apps-2.10.2}/idf_build_apps/args.py +53 -2
- {idf_build_apps-2.10.0 → idf_build_apps-2.10.2}/idf_build_apps/main.py +33 -30
- {idf_build_apps-2.10.0 → idf_build_apps-2.10.2}/idf_build_apps/manifest/manifest.py +14 -4
- {idf_build_apps-2.10.0 → idf_build_apps-2.10.2}/pyproject.toml +3 -2
- {idf_build_apps-2.10.0 → idf_build_apps-2.10.2}/setup.py +1 -1
- {idf_build_apps-2.10.0 → idf_build_apps-2.10.2}/tests/test_app.py +1 -2
- idf_build_apps-2.10.2/tests/test_manifest.py +561 -0
- idf_build_apps-2.10.0/tests/test_manifest.py +0 -568
- {idf_build_apps-2.10.0 → idf_build_apps-2.10.2}/.editorconfig +0 -0
- {idf_build_apps-2.10.0 → idf_build_apps-2.10.2}/.git-blame-ignore-revs +0 -0
- {idf_build_apps-2.10.0 → idf_build_apps-2.10.2}/.gitattributes +0 -0
- {idf_build_apps-2.10.0 → idf_build_apps-2.10.2}/.github/dependabot.yml +0 -0
- {idf_build_apps-2.10.0 → idf_build_apps-2.10.2}/.github/workflows/publish-pypi.yml +0 -0
- {idf_build_apps-2.10.0 → idf_build_apps-2.10.2}/.github/workflows/sync-jira.yml +0 -0
- {idf_build_apps-2.10.0 → idf_build_apps-2.10.2}/.github/workflows/test-build-docs.yml +0 -0
- {idf_build_apps-2.10.0 → idf_build_apps-2.10.2}/.github/workflows/test-build-idf-apps.yml +0 -0
- {idf_build_apps-2.10.0 → idf_build_apps-2.10.2}/.gitignore +0 -0
- {idf_build_apps-2.10.0 → idf_build_apps-2.10.2}/.readthedocs.yml +0 -0
- {idf_build_apps-2.10.0 → idf_build_apps-2.10.2}/CONTRIBUTING.md +0 -0
- {idf_build_apps-2.10.0 → idf_build_apps-2.10.2}/LICENSE +0 -0
- {idf_build_apps-2.10.0 → idf_build_apps-2.10.2}/README.md +0 -0
- {idf_build_apps-2.10.0 → idf_build_apps-2.10.2}/docs/_apidoc_templates/module.rst_t +0 -0
- {idf_build_apps-2.10.0 → idf_build_apps-2.10.2}/docs/_apidoc_templates/package.rst_t +0 -0
- {idf_build_apps-2.10.0 → idf_build_apps-2.10.2}/docs/_apidoc_templates/toc.rst_t +0 -0
- {idf_build_apps-2.10.0 → idf_build_apps-2.10.2}/docs/_static/espressif-logo.svg +0 -0
- {idf_build_apps-2.10.0 → idf_build_apps-2.10.2}/docs/_static/theme_overrides.css +0 -0
- {idf_build_apps-2.10.0 → idf_build_apps-2.10.2}/docs/_templates/layout.html +0 -0
- {idf_build_apps-2.10.0 → idf_build_apps-2.10.2}/docs/conf_common.py +0 -0
- {idf_build_apps-2.10.0 → idf_build_apps-2.10.2}/docs/en/Makefile +0 -0
- {idf_build_apps-2.10.0 → idf_build_apps-2.10.2}/docs/en/conf.py +0 -0
- {idf_build_apps-2.10.0 → idf_build_apps-2.10.2}/docs/en/explanations/build.rst +0 -0
- {idf_build_apps-2.10.0 → idf_build_apps-2.10.2}/docs/en/explanations/config_rules.rst +0 -0
- {idf_build_apps-2.10.0 → idf_build_apps-2.10.2}/docs/en/explanations/dependency_driven_build.rst +0 -0
- {idf_build_apps-2.10.0 → idf_build_apps-2.10.2}/docs/en/explanations/find.rst +0 -0
- {idf_build_apps-2.10.0 → idf_build_apps-2.10.2}/docs/en/guides/1.x_to_2.x.md +0 -0
- {idf_build_apps-2.10.0 → idf_build_apps-2.10.2}/docs/en/guides/custom_app.md +0 -0
- {idf_build_apps-2.10.0 → idf_build_apps-2.10.2}/docs/en/index.rst +0 -0
- {idf_build_apps-2.10.0 → idf_build_apps-2.10.2}/docs/en/others/CHANGELOG.md +0 -0
- {idf_build_apps-2.10.0 → idf_build_apps-2.10.2}/docs/en/others/CONTRIBUTING.md +0 -0
- {idf_build_apps-2.10.0 → idf_build_apps-2.10.2}/docs/en/references/cli.rst +0 -0
- {idf_build_apps-2.10.0 → idf_build_apps-2.10.2}/docs/en/references/config_file.rst +0 -0
- {idf_build_apps-2.10.0 → idf_build_apps-2.10.2}/docs/en/references/manifest.rst +0 -0
- {idf_build_apps-2.10.0 → idf_build_apps-2.10.2}/idf_build_apps/__main__.py +0 -0
- {idf_build_apps-2.10.0 → idf_build_apps-2.10.2}/idf_build_apps/autocompletions.py +0 -0
- {idf_build_apps-2.10.0 → idf_build_apps-2.10.2}/idf_build_apps/constants.py +0 -0
- {idf_build_apps-2.10.0 → idf_build_apps-2.10.2}/idf_build_apps/finder.py +0 -0
- {idf_build_apps-2.10.0 → idf_build_apps-2.10.2}/idf_build_apps/junit/__init__.py +0 -0
- {idf_build_apps-2.10.0 → idf_build_apps-2.10.2}/idf_build_apps/junit/report.py +0 -0
- {idf_build_apps-2.10.0 → idf_build_apps-2.10.2}/idf_build_apps/junit/utils.py +0 -0
- {idf_build_apps-2.10.0 → idf_build_apps-2.10.2}/idf_build_apps/log.py +0 -0
- {idf_build_apps-2.10.0 → idf_build_apps-2.10.2}/idf_build_apps/manifest/__init__.py +0 -0
- {idf_build_apps-2.10.0 → idf_build_apps-2.10.2}/idf_build_apps/manifest/soc_header.py +0 -0
- {idf_build_apps-2.10.0 → idf_build_apps-2.10.2}/idf_build_apps/py.typed +0 -0
- {idf_build_apps-2.10.0 → idf_build_apps-2.10.2}/idf_build_apps/session_args.py +0 -0
- {idf_build_apps-2.10.0 → idf_build_apps-2.10.2}/idf_build_apps/utils.py +0 -0
- {idf_build_apps-2.10.0 → idf_build_apps-2.10.2}/idf_build_apps/vendors/__init__.py +0 -0
- {idf_build_apps-2.10.0 → idf_build_apps-2.10.2}/idf_build_apps/vendors/pydantic_sources.py +0 -0
- {idf_build_apps-2.10.0 → idf_build_apps-2.10.2}/idf_build_apps/yaml/__init__.py +0 -0
- {idf_build_apps-2.10.0 → idf_build_apps-2.10.2}/idf_build_apps/yaml/parser.py +0 -0
- {idf_build_apps-2.10.0 → idf_build_apps-2.10.2}/license_header.txt +0 -0
- {idf_build_apps-2.10.0 → idf_build_apps-2.10.2}/tests/conftest.py +0 -0
- {idf_build_apps-2.10.0 → idf_build_apps-2.10.2}/tests/test_args.py +0 -0
- {idf_build_apps-2.10.0 → idf_build_apps-2.10.2}/tests/test_build.py +0 -0
- {idf_build_apps-2.10.0 → idf_build_apps-2.10.2}/tests/test_cmd.py +0 -0
- {idf_build_apps-2.10.0 → idf_build_apps-2.10.2}/tests/test_finder.py +0 -0
- {idf_build_apps-2.10.0 → idf_build_apps-2.10.2}/tests/test_utils.py +0 -0
|
@@ -2,6 +2,19 @@
|
|
|
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
|
+
|
|
12
|
+
## v2.10.1 (2025-05-05)
|
|
13
|
+
|
|
14
|
+
### Fix
|
|
15
|
+
|
|
16
|
+
- cache custom app classes
|
|
17
|
+
|
|
5
18
|
## v2.10.0 (2025-04-22)
|
|
6
19
|
|
|
7
20
|
### Feat
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: idf-build-apps
|
|
3
|
-
Version: 2.10.
|
|
3
|
+
Version: 2.10.2
|
|
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
|
|
7
7
|
Description-Content-Type: text/markdown
|
|
8
|
-
Classifier: Development Status ::
|
|
8
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
9
9
|
Classifier: License :: OSI Approved :: Apache Software License
|
|
10
10
|
Classifier: Programming Language :: Python :: 3.7
|
|
11
11
|
Classifier: Programming Language :: Python :: 3.8
|
|
@@ -13,6 +13,7 @@ Classifier: Programming Language :: Python :: 3.9
|
|
|
13
13
|
Classifier: Programming Language :: Python :: 3.10
|
|
14
14
|
Classifier: Programming Language :: Python :: 3.11
|
|
15
15
|
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
16
17
|
License-File: LICENSE
|
|
17
18
|
Requires-Dist: pyparsing
|
|
18
19
|
Requires-Dist: pyyaml
|
|
@@ -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.10.
|
|
11
|
+
__version__ = '2.10.2'
|
|
12
12
|
|
|
13
13
|
from .session_args import (
|
|
14
14
|
SessionArgs,
|
|
@@ -28,6 +28,7 @@ from .log import (
|
|
|
28
28
|
from .main import (
|
|
29
29
|
build_apps,
|
|
30
30
|
find_apps,
|
|
31
|
+
json_list_files_to_apps,
|
|
31
32
|
json_to_app,
|
|
32
33
|
)
|
|
33
34
|
|
|
@@ -38,6 +39,7 @@ __all__ = [
|
|
|
38
39
|
'MakeApp',
|
|
39
40
|
'build_apps',
|
|
40
41
|
'find_apps',
|
|
42
|
+
'json_list_files_to_apps',
|
|
41
43
|
'json_to_app',
|
|
42
44
|
'setup_logging',
|
|
43
45
|
]
|
|
@@ -1011,3 +1011,11 @@ class AppDeserializer(BaseModel):
|
|
|
1011
1011
|
def from_json(cls, json_data: t.Union[str, bytes, bytearray]) -> App:
|
|
1012
1012
|
json_dict = json.loads(json_data.strip())
|
|
1013
1013
|
return cls.model_validate({'app': json_dict}).app
|
|
1014
|
+
|
|
1015
|
+
@classmethod
|
|
1016
|
+
def from_json_list(cls, json_list: t.Sequence[t.Union[str, bytes, bytearray]]) -> t.List[App]:
|
|
1017
|
+
apps = []
|
|
1018
|
+
for app_json in json_list:
|
|
1019
|
+
apps.append(cls.from_json(app_json))
|
|
1020
|
+
|
|
1021
|
+
return apps
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
import argparse
|
|
5
5
|
import enum
|
|
6
6
|
import glob
|
|
7
|
+
import importlib
|
|
7
8
|
import inspect
|
|
8
9
|
import logging
|
|
9
10
|
import os
|
|
@@ -27,7 +28,7 @@ from pydantic_settings import (
|
|
|
27
28
|
)
|
|
28
29
|
from typing_extensions import Concatenate, ParamSpec
|
|
29
30
|
|
|
30
|
-
from . import SESSION_ARGS, App, setup_logging
|
|
31
|
+
from . import SESSION_ARGS, App, CMakeApp, MakeApp, setup_logging
|
|
31
32
|
from .constants import ALL_TARGETS, IDF_BUILD_APPS_TOML_FN, SUPPORTED_TARGETS
|
|
32
33
|
from .manifest.manifest import FolderRule, Manifest
|
|
33
34
|
from .utils import InvalidCommand, files_matches_patterns, semicolon_separated_str_to_list, to_absolute_path, to_list
|
|
@@ -397,6 +398,12 @@ class DependencyDrivenBuildArguments(GlobalArguments):
|
|
|
397
398
|
|
|
398
399
|
|
|
399
400
|
class FindBuildArguments(DependencyDrivenBuildArguments):
|
|
401
|
+
_KNOWN_APP_CLASSES: t.ClassVar[t.Dict[str, t.Type[App]]] = {
|
|
402
|
+
'cmake': CMakeApp,
|
|
403
|
+
'make': MakeApp,
|
|
404
|
+
}
|
|
405
|
+
_LOADED_MODULE_APPS: t.ClassVar[t.Dict[str, t.Type[App]]] = {}
|
|
406
|
+
|
|
400
407
|
paths: t.List[str] = field(
|
|
401
408
|
FieldMetadata(
|
|
402
409
|
validate_method=[ValidateMethod.TO_LIST],
|
|
@@ -586,12 +593,56 @@ class FindBuildArguments(DependencyDrivenBuildArguments):
|
|
|
586
593
|
|
|
587
594
|
if self.disable_targets and FolderRule.DEFAULT_BUILD_TARGETS:
|
|
588
595
|
LOGGER.info('Disable targets: %s', self.disable_targets)
|
|
589
|
-
self.default_build_targets = [
|
|
596
|
+
self.default_build_targets = [
|
|
597
|
+
_target for _target in FolderRule.DEFAULT_BUILD_TARGETS if _target not in self.disable_targets
|
|
598
|
+
]
|
|
590
599
|
FolderRule.DEFAULT_BUILD_TARGETS = self.default_build_targets
|
|
591
600
|
|
|
592
601
|
if self.override_sdkconfig_files or self.override_sdkconfig_items:
|
|
593
602
|
SESSION_ARGS.set(self)
|
|
594
603
|
|
|
604
|
+
# load build system
|
|
605
|
+
# here could be a string or a class of type App
|
|
606
|
+
if not isinstance(self.build_system, str):
|
|
607
|
+
# do nothing, only cache
|
|
608
|
+
self._KNOWN_APP_CLASSES[self.build_system('', '').build_system] = self.build_system
|
|
609
|
+
return
|
|
610
|
+
|
|
611
|
+
# here could only be a string
|
|
612
|
+
if self.build_system in self._KNOWN_APP_CLASSES:
|
|
613
|
+
self.build_system = self._KNOWN_APP_CLASSES[self.build_system]
|
|
614
|
+
return
|
|
615
|
+
|
|
616
|
+
if ':' not in self.build_system:
|
|
617
|
+
raise ValueError(
|
|
618
|
+
f'Invalid build system: {self.build_system}. '
|
|
619
|
+
f'Known build systems: {", ".join(self._KNOWN_APP_CLASSES.keys())}'
|
|
620
|
+
)
|
|
621
|
+
|
|
622
|
+
# here could only be a string in format "module:class"
|
|
623
|
+
if self.build_system in self._LOADED_MODULE_APPS:
|
|
624
|
+
self.build_system = self._LOADED_MODULE_APPS[self.build_system]
|
|
625
|
+
return
|
|
626
|
+
|
|
627
|
+
# here could only be a string in format "module:class", and not loaded yet
|
|
628
|
+
module_path, class_name = self.build_system.split(':')
|
|
629
|
+
try:
|
|
630
|
+
module = importlib.import_module(module_path)
|
|
631
|
+
except ImportError as e:
|
|
632
|
+
raise ImportError(f'Failed to import module {module_path}. Error: {e!s}')
|
|
633
|
+
|
|
634
|
+
try:
|
|
635
|
+
app_cls = getattr(module, class_name)
|
|
636
|
+
if not issubclass(app_cls, App):
|
|
637
|
+
raise ValueError(f'Class {class_name} must be a subclass of App')
|
|
638
|
+
except (ValueError, AttributeError):
|
|
639
|
+
raise ValueError(f'Class {class_name} not found in module {module_path}')
|
|
640
|
+
|
|
641
|
+
self._LOADED_MODULE_APPS[self.build_system] = app_cls
|
|
642
|
+
self._KNOWN_APP_CLASSES[app_cls('', '').build_system] = app_cls
|
|
643
|
+
|
|
644
|
+
self.build_system = app_cls
|
|
645
|
+
|
|
595
646
|
|
|
596
647
|
class FindArguments(FindBuildArguments):
|
|
597
648
|
output: t.Optional[str] = field(
|
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
# SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
|
|
6
6
|
import argparse
|
|
7
|
-
import importlib
|
|
8
7
|
import json
|
|
9
8
|
import logging
|
|
10
9
|
import os
|
|
@@ -30,8 +29,6 @@ from idf_build_apps.args import (
|
|
|
30
29
|
from .app import (
|
|
31
30
|
App,
|
|
32
31
|
AppDeserializer,
|
|
33
|
-
CMakeApp,
|
|
34
|
-
MakeApp,
|
|
35
32
|
)
|
|
36
33
|
from .autocompletions import activate_completions
|
|
37
34
|
from .constants import ALL_TARGETS, BuildStatus, completion_instructions
|
|
@@ -89,29 +86,6 @@ def find_apps(
|
|
|
89
86
|
**kwargs,
|
|
90
87
|
)
|
|
91
88
|
|
|
92
|
-
app_cls: t.Type[App]
|
|
93
|
-
if isinstance(find_arguments.build_system, str):
|
|
94
|
-
if find_arguments.build_system == 'cmake':
|
|
95
|
-
app_cls = CMakeApp
|
|
96
|
-
elif find_arguments.build_system == 'make':
|
|
97
|
-
app_cls = MakeApp
|
|
98
|
-
elif ':' in find_arguments.build_system:
|
|
99
|
-
# Custom App class in format "module:class"
|
|
100
|
-
try:
|
|
101
|
-
module_path, class_name = find_arguments.build_system.split(':')
|
|
102
|
-
module = importlib.import_module(module_path)
|
|
103
|
-
app_cls = getattr(module, class_name)
|
|
104
|
-
if not issubclass(app_cls, App):
|
|
105
|
-
raise ValueError(f'Class {class_name} must be a subclass of App')
|
|
106
|
-
except (ValueError, ImportError, AttributeError) as e:
|
|
107
|
-
raise ValueError(f'Invalid custom App class path: {find_arguments.build_system}. Error: {e!s}')
|
|
108
|
-
else:
|
|
109
|
-
raise ValueError(
|
|
110
|
-
'build_system must be either "cmake", "make" or a custom App class path in format "module:class"'
|
|
111
|
-
)
|
|
112
|
-
else:
|
|
113
|
-
app_cls = find_arguments.build_system
|
|
114
|
-
|
|
115
89
|
apps: t.Set[App] = set()
|
|
116
90
|
if find_arguments.target == 'all':
|
|
117
91
|
targets = ALL_TARGETS
|
|
@@ -127,7 +101,7 @@ def find_apps(
|
|
|
127
101
|
_find_apps(
|
|
128
102
|
_p,
|
|
129
103
|
_t,
|
|
130
|
-
app_cls=
|
|
104
|
+
app_cls=find_arguments.build_system, # type: ignore
|
|
131
105
|
args=find_arguments,
|
|
132
106
|
)
|
|
133
107
|
)
|
|
@@ -499,14 +473,43 @@ def json_to_app(json_str: str, extra_classes: t.Optional[t.List[t.Type[App]]] =
|
|
|
499
473
|
:param extra_classes: extra App class
|
|
500
474
|
:return: App object
|
|
501
475
|
"""
|
|
502
|
-
|
|
476
|
+
_known_classes = list(FindArguments()._KNOWN_APP_CLASSES.values())
|
|
503
477
|
if extra_classes:
|
|
504
|
-
|
|
478
|
+
_known_classes.extend(extra_classes)
|
|
505
479
|
|
|
506
480
|
custom_deserializer = create_model(
|
|
507
481
|
'_CustomDeserializer',
|
|
508
|
-
app=(t.Union[tuple(
|
|
482
|
+
app=(t.Union[tuple(_known_classes)], Field(discriminator='build_system')),
|
|
509
483
|
__base__=AppDeserializer,
|
|
510
484
|
)
|
|
511
485
|
|
|
512
486
|
return custom_deserializer.from_json(json_str)
|
|
487
|
+
|
|
488
|
+
|
|
489
|
+
def json_list_files_to_apps(
|
|
490
|
+
json_list_filepaths: t.List[str],
|
|
491
|
+
extra_classes: t.Optional[t.List[t.Type[App]]] = None,
|
|
492
|
+
) -> t.List[App]:
|
|
493
|
+
"""
|
|
494
|
+
Deserialize a list of json strings to App objects
|
|
495
|
+
|
|
496
|
+
:param json_list_filepaths: filepath to the files, each line is a json string
|
|
497
|
+
:param extra_classes: extra App class
|
|
498
|
+
:return: list of App object
|
|
499
|
+
"""
|
|
500
|
+
_known_classes = list(FindArguments()._KNOWN_APP_CLASSES.values())
|
|
501
|
+
if extra_classes:
|
|
502
|
+
_known_classes.extend(extra_classes)
|
|
503
|
+
|
|
504
|
+
custom_deserializer = create_model(
|
|
505
|
+
'_CustomDeserializer',
|
|
506
|
+
app=(t.Union[tuple(_known_classes)], Field(discriminator='build_system')),
|
|
507
|
+
__base__=AppDeserializer,
|
|
508
|
+
)
|
|
509
|
+
|
|
510
|
+
jsons = []
|
|
511
|
+
for fp in json_list_filepaths:
|
|
512
|
+
with open(fp) as fr:
|
|
513
|
+
jsons.extend(fr.readlines())
|
|
514
|
+
|
|
515
|
+
return custom_deserializer.from_json_list(jsons)
|
|
@@ -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
|
|
|
@@ -10,7 +10,7 @@ authors = [
|
|
|
10
10
|
readme = "README.md"
|
|
11
11
|
license = {file = "LICENSE"}
|
|
12
12
|
classifiers = [
|
|
13
|
-
"Development Status ::
|
|
13
|
+
"Development Status :: 5 - Production/Stable",
|
|
14
14
|
"License :: OSI Approved :: Apache Software License",
|
|
15
15
|
"Programming Language :: Python :: 3.7",
|
|
16
16
|
"Programming Language :: Python :: 3.8",
|
|
@@ -18,6 +18,7 @@ classifiers = [
|
|
|
18
18
|
"Programming Language :: Python :: 3.10",
|
|
19
19
|
"Programming Language :: Python :: 3.11",
|
|
20
20
|
"Programming Language :: Python :: 3.12",
|
|
21
|
+
"Programming Language :: Python :: 3.13",
|
|
21
22
|
]
|
|
22
23
|
dynamic = ["version", "description"]
|
|
23
24
|
requires-python = ">=3.7"
|
|
@@ -64,7 +65,7 @@ idf-build-apps = "idf_build_apps:main.main"
|
|
|
64
65
|
|
|
65
66
|
[tool.commitizen]
|
|
66
67
|
name = "cz_conventional_commits"
|
|
67
|
-
version = "2.10.
|
|
68
|
+
version = "2.10.2"
|
|
68
69
|
tag_format = "v$version"
|
|
69
70
|
version_files = [
|
|
70
71
|
"idf_build_apps/__init__.py",
|
|
@@ -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>',
|
|
@@ -79,8 +79,7 @@ def test_app_deserializer():
|
|
|
79
79
|
|
|
80
80
|
with pytest.raises(
|
|
81
81
|
ValidationError,
|
|
82
|
-
match="Input tag 'custom' found using 'build_system' does not match "
|
|
83
|
-
"any of the expected tags: 'unknown', 'cmake', 'make'",
|
|
82
|
+
match="Input tag 'custom' found using 'build_system' does not match any of the expected tags: 'cmake', 'make'",
|
|
84
83
|
):
|
|
85
84
|
assert json_to_app(c.to_json()) == c
|
|
86
85
|
|