idf-build-apps 2.5.3__py3-none-any.whl → 2.6.0__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 +65 -54
- idf_build_apps/finder.py +1 -0
- idf_build_apps/junit/utils.py +1 -1
- idf_build_apps/manifest/soc_header.py +1 -1
- idf_build_apps/py.typed +0 -0
- idf_build_apps/vendors/pydantic_sources.py +51 -34
- {idf_build_apps-2.5.3.dist-info → idf_build_apps-2.6.0.dist-info}/METADATA +4 -3
- {idf_build_apps-2.5.3.dist-info → idf_build_apps-2.6.0.dist-info}/RECORD +12 -11
- {idf_build_apps-2.5.3.dist-info → idf_build_apps-2.6.0.dist-info}/WHEEL +1 -1
- {idf_build_apps-2.5.3.dist-info → idf_build_apps-2.6.0.dist-info}/LICENSE +0 -0
- {idf_build_apps-2.5.3.dist-info → idf_build_apps-2.6.0.dist-info}/entry_points.txt +0 -0
idf_build_apps/__init__.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# SPDX-FileCopyrightText: 2022-
|
|
1
|
+
# SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
|
2
2
|
# SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
4
|
"""
|
|
@@ -8,7 +8,7 @@ Tools for building ESP-IDF related apps.
|
|
|
8
8
|
# ruff: noqa: E402
|
|
9
9
|
# avoid circular imports
|
|
10
10
|
|
|
11
|
-
__version__ = '2.
|
|
11
|
+
__version__ = '2.6.0'
|
|
12
12
|
|
|
13
13
|
from .session_args import (
|
|
14
14
|
SessionArgs,
|
idf_build_apps/args.py
CHANGED
|
@@ -27,7 +27,7 @@ from pydantic_settings import (
|
|
|
27
27
|
from typing_extensions import Concatenate, ParamSpec
|
|
28
28
|
|
|
29
29
|
from . import SESSION_ARGS, App, setup_logging
|
|
30
|
-
from .constants import ALL_TARGETS
|
|
30
|
+
from .constants import ALL_TARGETS, IDF_BUILD_APPS_TOML_FN
|
|
31
31
|
from .manifest.manifest import FolderRule, Manifest
|
|
32
32
|
from .utils import InvalidCommand, files_matches_patterns, semicolon_separated_str_to_list, to_absolute_path, to_list
|
|
33
33
|
from .vendors.pydantic_sources import PyprojectTomlConfigSettingsSource, TomlConfigSettingsSource
|
|
@@ -37,6 +37,7 @@ LOGGER = logging.getLogger(__name__)
|
|
|
37
37
|
|
|
38
38
|
class ValidateMethod(str, enum.Enum):
|
|
39
39
|
TO_LIST = 'to_list'
|
|
40
|
+
EXPAND_VARS = 'expand_vars'
|
|
40
41
|
|
|
41
42
|
|
|
42
43
|
@dataclass
|
|
@@ -115,10 +116,11 @@ class BaseArguments(BaseSettings):
|
|
|
115
116
|
"""Base settings class for all settings classes"""
|
|
116
117
|
|
|
117
118
|
model_config = SettingsConfigDict(
|
|
118
|
-
toml_file=
|
|
119
|
+
toml_file=IDF_BUILD_APPS_TOML_FN,
|
|
120
|
+
# these below two are supported in pydantic 2.6
|
|
119
121
|
pyproject_toml_table_header=('tool', 'idf-build-apps'),
|
|
120
122
|
pyproject_toml_depth=sys.maxsize,
|
|
121
|
-
extra='ignore',
|
|
123
|
+
extra='ignore', # we're supporting pydantic <2.6 as well, so we ignore extra fields
|
|
122
124
|
)
|
|
123
125
|
|
|
124
126
|
@classmethod
|
|
@@ -143,8 +145,15 @@ class BaseArguments(BaseSettings):
|
|
|
143
145
|
f = cls.model_fields[info.field_name]
|
|
144
146
|
meta = get_meta(f)
|
|
145
147
|
if meta and meta.validate_method:
|
|
146
|
-
|
|
147
|
-
|
|
148
|
+
for method in meta.validate_method:
|
|
149
|
+
if method == ValidateMethod.TO_LIST:
|
|
150
|
+
v = to_list(v)
|
|
151
|
+
elif method == ValidateMethod.EXPAND_VARS:
|
|
152
|
+
v = os.path.expandvars(v)
|
|
153
|
+
else:
|
|
154
|
+
raise NotImplementedError(f'Unknown validate method: {method}')
|
|
155
|
+
|
|
156
|
+
return v
|
|
148
157
|
|
|
149
158
|
return v
|
|
150
159
|
|
|
@@ -156,19 +165,19 @@ class GlobalArguments(BaseArguments):
|
|
|
156
165
|
action='count',
|
|
157
166
|
),
|
|
158
167
|
description='Verbosity level. By default set to WARNING. Specify -v for INFO, -vv for DEBUG',
|
|
159
|
-
default=0,
|
|
168
|
+
default=0, # type: ignore
|
|
160
169
|
)
|
|
161
170
|
log_file: t.Optional[str] = field(
|
|
162
171
|
None,
|
|
163
172
|
description='Path to the log file, if not specified logs will be printed to stderr',
|
|
164
|
-
default=None,
|
|
173
|
+
default=None, # type: ignore
|
|
165
174
|
)
|
|
166
175
|
no_color: bool = field(
|
|
167
176
|
FieldMetadata(
|
|
168
177
|
action='store_true',
|
|
169
178
|
),
|
|
170
179
|
description='Disable colored output',
|
|
171
|
-
default=False,
|
|
180
|
+
default=False, # type: ignore
|
|
172
181
|
)
|
|
173
182
|
|
|
174
183
|
def model_post_init(self, __context: Any) -> None:
|
|
@@ -190,7 +199,7 @@ class DependencyDrivenBuildArguments(GlobalArguments):
|
|
|
190
199
|
),
|
|
191
200
|
description='Path to the manifest files which contains the build test rules of the apps',
|
|
192
201
|
validation_alias=AliasChoices('manifest_files', 'manifest_file'),
|
|
193
|
-
default=None,
|
|
202
|
+
default=None, # type: ignore
|
|
194
203
|
)
|
|
195
204
|
manifest_filepatterns: t.Optional[t.List[str]] = field(
|
|
196
205
|
FieldMetadata(
|
|
@@ -199,13 +208,15 @@ class DependencyDrivenBuildArguments(GlobalArguments):
|
|
|
199
208
|
),
|
|
200
209
|
description='space-separated list of file patterns to search for the manifest files. '
|
|
201
210
|
'The matched files will be loaded as the manifest files.',
|
|
202
|
-
default=None,
|
|
211
|
+
default=None, # type: ignore
|
|
203
212
|
)
|
|
204
213
|
manifest_rootpath: str = field(
|
|
205
|
-
|
|
214
|
+
FieldMetadata(
|
|
215
|
+
validate_method=[ValidateMethod.EXPAND_VARS],
|
|
216
|
+
),
|
|
206
217
|
description='Root path to resolve the relative paths defined in the manifest files. '
|
|
207
|
-
'By default set to the current directory',
|
|
208
|
-
default=os.curdir,
|
|
218
|
+
'By default set to the current directory. Support environment variables.',
|
|
219
|
+
default=os.curdir, # type: ignore
|
|
209
220
|
)
|
|
210
221
|
modified_components: t.Optional[t.List[str]] = field(
|
|
211
222
|
FieldMetadata(
|
|
@@ -215,7 +226,7 @@ class DependencyDrivenBuildArguments(GlobalArguments):
|
|
|
215
226
|
description='semicolon-separated list of modified components. '
|
|
216
227
|
'If set to "", the value would be considered as None. '
|
|
217
228
|
'If set to ";", the value would be considered as an empty list.',
|
|
218
|
-
default=None,
|
|
229
|
+
default=None, # type: ignore
|
|
219
230
|
)
|
|
220
231
|
modified_files: t.Optional[t.List[str]] = field(
|
|
221
232
|
FieldMetadata(
|
|
@@ -225,7 +236,7 @@ class DependencyDrivenBuildArguments(GlobalArguments):
|
|
|
225
236
|
description='semicolon-separated list of modified files. '
|
|
226
237
|
'If set to "", the value would be considered as None. '
|
|
227
238
|
'If set to ";", the value would be considered as an empty list.',
|
|
228
|
-
default=None,
|
|
239
|
+
default=None, # type: ignore
|
|
229
240
|
)
|
|
230
241
|
deactivate_dependency_driven_build_by_components: t.Optional[t.List[str]] = field(
|
|
231
242
|
FieldMetadata(
|
|
@@ -247,7 +258,7 @@ class DependencyDrivenBuildArguments(GlobalArguments):
|
|
|
247
258
|
validation_alias=AliasChoices(
|
|
248
259
|
'deactivate_dependency_driven_build_by_components', 'ignore_app_dependencies_components'
|
|
249
260
|
),
|
|
250
|
-
default=None,
|
|
261
|
+
default=None, # type: ignore
|
|
251
262
|
)
|
|
252
263
|
deactivate_dependency_driven_build_by_filepatterns: t.Optional[t.List[str]] = field(
|
|
253
264
|
FieldMetadata(
|
|
@@ -269,21 +280,21 @@ class DependencyDrivenBuildArguments(GlobalArguments):
|
|
|
269
280
|
validation_alias=AliasChoices(
|
|
270
281
|
'deactivate_dependency_driven_build_by_filepatterns', 'ignore_app_dependencies_filepatterns'
|
|
271
282
|
),
|
|
272
|
-
default=None,
|
|
283
|
+
default=None, # type: ignore
|
|
273
284
|
)
|
|
274
285
|
check_manifest_rules: bool = field(
|
|
275
286
|
FieldMetadata(
|
|
276
287
|
action='store_true',
|
|
277
288
|
),
|
|
278
289
|
description='Check if all folders defined in the manifest files exist. Fail if not',
|
|
279
|
-
default=False,
|
|
290
|
+
default=False, # type: ignore
|
|
280
291
|
)
|
|
281
292
|
compare_manifest_sha_filepath: t.Optional[str] = field(
|
|
282
293
|
None,
|
|
283
294
|
description='Path to the file containing the hash of the manifest rules. '
|
|
284
295
|
'Compare the hash with the current manifest rules. '
|
|
285
296
|
'All matched apps will be built if the corresponding manifest rule is modified',
|
|
286
|
-
default=None,
|
|
297
|
+
default=None, # type: ignore
|
|
287
298
|
)
|
|
288
299
|
|
|
289
300
|
def model_post_init(self, __context: Any) -> None:
|
|
@@ -377,28 +388,28 @@ class FindBuildArguments(DependencyDrivenBuildArguments):
|
|
|
377
388
|
nargs='*',
|
|
378
389
|
),
|
|
379
390
|
description='Paths to the directories containing the apps. By default set to the current directory',
|
|
380
|
-
default=os.curdir,
|
|
391
|
+
default=os.curdir, # type: ignore
|
|
381
392
|
)
|
|
382
393
|
target: str = field(
|
|
383
394
|
FieldMetadata(
|
|
384
395
|
shorthand='-t',
|
|
385
396
|
),
|
|
386
397
|
description='Filter the apps by target. By default set to "all"',
|
|
387
|
-
default='all',
|
|
398
|
+
default='all', # type: ignore
|
|
388
399
|
)
|
|
389
400
|
build_system: t.Union[str, t.Type[App]] = field(
|
|
390
401
|
FieldMetadata(
|
|
391
402
|
choices=['cmake', 'make'],
|
|
392
403
|
),
|
|
393
404
|
description='Filter the apps by build system. By default set to "cmake"',
|
|
394
|
-
default='cmake',
|
|
405
|
+
default='cmake', # type: ignore
|
|
395
406
|
)
|
|
396
407
|
recursive: bool = field(
|
|
397
408
|
FieldMetadata(
|
|
398
409
|
action='store_true',
|
|
399
410
|
),
|
|
400
411
|
description='Search for apps recursively under the specified paths',
|
|
401
|
-
default=False,
|
|
412
|
+
default=False, # type: ignore
|
|
402
413
|
)
|
|
403
414
|
exclude: t.Optional[t.List[str]] = field(
|
|
404
415
|
FieldMetadata(
|
|
@@ -407,20 +418,20 @@ class FindBuildArguments(DependencyDrivenBuildArguments):
|
|
|
407
418
|
),
|
|
408
419
|
description='Ignore the specified directories while searching recursively',
|
|
409
420
|
validation_alias=AliasChoices('exclude', 'exclude_list'),
|
|
410
|
-
default=None,
|
|
421
|
+
default=None, # type: ignore
|
|
411
422
|
)
|
|
412
423
|
work_dir: t.Optional[str] = field(
|
|
413
424
|
None,
|
|
414
425
|
description='Copy the app to this directory before building. '
|
|
415
426
|
'By default set to the app directory. Can expand placeholders',
|
|
416
|
-
default=None,
|
|
427
|
+
default=None, # type: ignore
|
|
417
428
|
)
|
|
418
429
|
build_dir: str = field(
|
|
419
430
|
None,
|
|
420
431
|
description='Build directory for the app. By default set to "build". '
|
|
421
432
|
'When set to relative path, it will be treated as relative to the app directory. '
|
|
422
433
|
'Can expand placeholders',
|
|
423
|
-
default='build',
|
|
434
|
+
default='build', # type: ignore
|
|
424
435
|
)
|
|
425
436
|
build_log_filename: t.Optional[str] = field(
|
|
426
437
|
FieldMetadata(
|
|
@@ -428,7 +439,7 @@ class FindBuildArguments(DependencyDrivenBuildArguments):
|
|
|
428
439
|
),
|
|
429
440
|
description='Log filename under the build directory instead of stdout. Can expand placeholders',
|
|
430
441
|
validation_alias=AliasChoices('build_log_filename', 'build_log'),
|
|
431
|
-
default=None,
|
|
442
|
+
default=None, # type: ignore
|
|
432
443
|
)
|
|
433
444
|
size_json_filename: t.Optional[str] = field(
|
|
434
445
|
FieldMetadata(
|
|
@@ -436,7 +447,7 @@ class FindBuildArguments(DependencyDrivenBuildArguments):
|
|
|
436
447
|
),
|
|
437
448
|
description='`idf.py size` output file under the build directory when specified. ' 'Can expand placeholders',
|
|
438
449
|
validation_alias=AliasChoices('size_json_filename', 'size_file'),
|
|
439
|
-
default=None,
|
|
450
|
+
default=None, # type: ignore
|
|
440
451
|
)
|
|
441
452
|
config_rules: t.Optional[t.List[str]] = field(
|
|
442
453
|
FieldMetadata(
|
|
@@ -454,31 +465,31 @@ class FindBuildArguments(DependencyDrivenBuildArguments):
|
|
|
454
465
|
'FILEPATTERN is the filename of the sdkconfig file with a single wildcard character (*). '
|
|
455
466
|
'The NAME is the value matched by the wildcard',
|
|
456
467
|
validation_alias=AliasChoices('config_rules', 'config_rules_str', 'config'),
|
|
457
|
-
default=None,
|
|
468
|
+
default=None, # type: ignore
|
|
458
469
|
)
|
|
459
470
|
override_sdkconfig_items: t.Optional[str] = field(
|
|
460
471
|
None,
|
|
461
472
|
description='A comma-separated list of key=value pairs to override the sdkconfig items',
|
|
462
|
-
default=None,
|
|
473
|
+
default=None, # type: ignore
|
|
463
474
|
)
|
|
464
475
|
override_sdkconfig_files: t.Optional[str] = field(
|
|
465
476
|
None,
|
|
466
477
|
description='A comma-separated list of sdkconfig files to override the sdkconfig items. '
|
|
467
478
|
'When set to relative path, it will be treated as relative to the current directory',
|
|
468
|
-
default=None,
|
|
479
|
+
default=None, # type: ignore
|
|
469
480
|
)
|
|
470
481
|
sdkconfig_defaults: t.Optional[str] = field(
|
|
471
482
|
None,
|
|
472
483
|
description='A semicolon-separated list of sdkconfig files passed to `idf.py -DSDKCONFIG_DEFAULTS`. '
|
|
473
484
|
'SDKCONFIG_DEFAULTS environment variable is used when not specified',
|
|
474
|
-
default=os.getenv('SDKCONFIG_DEFAULTS', None),
|
|
485
|
+
default=os.getenv('SDKCONFIG_DEFAULTS', None), # type: ignore
|
|
475
486
|
)
|
|
476
487
|
check_warnings: bool = field(
|
|
477
488
|
FieldMetadata(
|
|
478
489
|
action='store_true',
|
|
479
490
|
),
|
|
480
491
|
description='Check for warnings in the build output. Fail if any warnings are found',
|
|
481
|
-
default=False,
|
|
492
|
+
default=False, # type: ignore
|
|
482
493
|
)
|
|
483
494
|
default_build_targets: t.Optional[t.List[str]] = field(
|
|
484
495
|
FieldMetadata(
|
|
@@ -487,7 +498,7 @@ class FindBuildArguments(DependencyDrivenBuildArguments):
|
|
|
487
498
|
),
|
|
488
499
|
description='space-separated list of the default enabled build targets for the apps. '
|
|
489
500
|
'When not specified, the default value is the targets listed by `idf.py --list-targets`',
|
|
490
|
-
default=None,
|
|
501
|
+
default=None, # type: ignore
|
|
491
502
|
)
|
|
492
503
|
enable_preview_targets: bool = field(
|
|
493
504
|
FieldMetadata(
|
|
@@ -495,28 +506,28 @@ class FindBuildArguments(DependencyDrivenBuildArguments):
|
|
|
495
506
|
),
|
|
496
507
|
description='When enabled, the default build targets will be set to all apps, '
|
|
497
508
|
'including the preview targets. As the targets defined in `idf.py --list-targets --preview`',
|
|
498
|
-
default=False,
|
|
509
|
+
default=False, # type: ignore
|
|
499
510
|
)
|
|
500
511
|
include_skipped_apps: bool = field(
|
|
501
512
|
FieldMetadata(
|
|
502
513
|
action='store_true',
|
|
503
514
|
),
|
|
504
515
|
description='Include the skipped apps in the output, together with the enabled ones',
|
|
505
|
-
default=False,
|
|
516
|
+
default=False, # type: ignore
|
|
506
517
|
)
|
|
507
518
|
include_disabled_apps: bool = field(
|
|
508
519
|
FieldMetadata(
|
|
509
520
|
action='store_true',
|
|
510
521
|
),
|
|
511
522
|
description='Include the disabled apps in the output, together with the enabled ones',
|
|
512
|
-
default=False,
|
|
523
|
+
default=False, # type: ignore
|
|
513
524
|
)
|
|
514
525
|
include_all_apps: bool = field(
|
|
515
526
|
FieldMetadata(
|
|
516
527
|
action='store_true',
|
|
517
528
|
),
|
|
518
529
|
description='Include skipped, and disabled apps in the output, together with the enabled ones',
|
|
519
|
-
default=False,
|
|
530
|
+
default=False, # type: ignore
|
|
520
531
|
)
|
|
521
532
|
|
|
522
533
|
def model_post_init(self, __context: Any) -> None:
|
|
@@ -557,7 +568,7 @@ class FindArguments(FindBuildArguments):
|
|
|
557
568
|
shorthand='-o',
|
|
558
569
|
),
|
|
559
570
|
description='Record the found apps to the specified file instead of stdout',
|
|
560
|
-
default=None,
|
|
571
|
+
default=None, # type: ignore
|
|
561
572
|
)
|
|
562
573
|
output_format: str = field(
|
|
563
574
|
FieldMetadata(
|
|
@@ -566,7 +577,7 @@ class FindArguments(FindBuildArguments):
|
|
|
566
577
|
description='Output format of the found apps. '
|
|
567
578
|
'In "raw" format, each line is a json string serialized from the app model. '
|
|
568
579
|
'In "json" format, the output is a json list of the serialized app models',
|
|
569
|
-
default='raw',
|
|
580
|
+
default='raw', # type: ignore
|
|
570
581
|
)
|
|
571
582
|
|
|
572
583
|
def model_post_init(self, __context: Any) -> None:
|
|
@@ -587,7 +598,7 @@ class BuildArguments(FindBuildArguments):
|
|
|
587
598
|
action='store_true',
|
|
588
599
|
),
|
|
589
600
|
description='Enable verbose output of the build system',
|
|
590
|
-
default=False,
|
|
601
|
+
default=False, # type: ignore
|
|
591
602
|
)
|
|
592
603
|
parallel_count: int = field(
|
|
593
604
|
FieldMetadata(
|
|
@@ -597,7 +608,7 @@ class BuildArguments(FindBuildArguments):
|
|
|
597
608
|
'Specified together with --parallel-index. '
|
|
598
609
|
'The given apps will be divided into parallel_count parts, '
|
|
599
610
|
'and the current run will build the parallel_index-th part',
|
|
600
|
-
default=1,
|
|
611
|
+
default=1, # type: ignore
|
|
601
612
|
)
|
|
602
613
|
parallel_index: int = field(
|
|
603
614
|
FieldMetadata(
|
|
@@ -607,28 +618,28 @@ class BuildArguments(FindBuildArguments):
|
|
|
607
618
|
'Specified together with --parallel-count. '
|
|
608
619
|
'The given apps will be divided into parallel_count parts, '
|
|
609
620
|
'and the current run will build the parallel_index-th part',
|
|
610
|
-
default=1,
|
|
621
|
+
default=1, # type: ignore
|
|
611
622
|
)
|
|
612
623
|
dry_run: bool = field(
|
|
613
624
|
FieldMetadata(
|
|
614
625
|
action='store_true',
|
|
615
626
|
),
|
|
616
627
|
description='Skip the actual build, only print the build process',
|
|
617
|
-
default=False,
|
|
628
|
+
default=False, # type: ignore
|
|
618
629
|
)
|
|
619
630
|
keep_going: bool = field(
|
|
620
631
|
FieldMetadata(
|
|
621
632
|
action='store_true',
|
|
622
633
|
),
|
|
623
634
|
description='Continue building the next app when the current build fails',
|
|
624
|
-
default=False,
|
|
635
|
+
default=False, # type: ignore
|
|
625
636
|
)
|
|
626
637
|
no_preserve: bool = field(
|
|
627
638
|
FieldMetadata(
|
|
628
639
|
action='store_true',
|
|
629
640
|
),
|
|
630
641
|
description='Do not preserve the build directory after a successful build',
|
|
631
|
-
default=False,
|
|
642
|
+
default=False, # type: ignore
|
|
632
643
|
)
|
|
633
644
|
ignore_warning_strs: t.Optional[t.List[str]] = field(
|
|
634
645
|
FieldMetadata(
|
|
@@ -641,7 +652,7 @@ class BuildArguments(FindBuildArguments):
|
|
|
641
652
|
description='space-separated list of patterns. '
|
|
642
653
|
'Ignore the warnings in the build output that match the patterns',
|
|
643
654
|
validation_alias=AliasChoices('ignore_warning_strs', 'ignore_warning_str'),
|
|
644
|
-
default=None,
|
|
655
|
+
default=None, # type: ignore
|
|
645
656
|
)
|
|
646
657
|
ignore_warning_files: t.Optional[t.List[t.Union[str, TextIOWrapper]]] = field(
|
|
647
658
|
FieldMetadata(
|
|
@@ -656,14 +667,14 @@ class BuildArguments(FindBuildArguments):
|
|
|
656
667
|
),
|
|
657
668
|
description='Path to the files containing the patterns to ignore the warnings in the build output',
|
|
658
669
|
validation_alias=AliasChoices('ignore_warning_files', 'ignore_warning_file'),
|
|
659
|
-
default=None,
|
|
670
|
+
default=None, # type: ignore
|
|
660
671
|
)
|
|
661
672
|
copy_sdkconfig: bool = field(
|
|
662
673
|
FieldMetadata(
|
|
663
674
|
action='store_true',
|
|
664
675
|
),
|
|
665
676
|
description='Copy the sdkconfig file to the build directory',
|
|
666
|
-
default=False,
|
|
677
|
+
default=False, # type: ignore
|
|
667
678
|
)
|
|
668
679
|
|
|
669
680
|
# Attrs that support placeholders
|
|
@@ -675,7 +686,7 @@ class BuildArguments(FindBuildArguments):
|
|
|
675
686
|
description='Record size json filepath of the built apps to the specified file. '
|
|
676
687
|
'Each line is a json string. Can expand placeholders @p',
|
|
677
688
|
validation_alias=AliasChoices('collect_size_info_filename', 'collect_size_info'),
|
|
678
|
-
default=None,
|
|
689
|
+
default=None, # type: ignore
|
|
679
690
|
exclude=True, # computed field is used
|
|
680
691
|
)
|
|
681
692
|
collect_app_info_filename: t.Optional[str] = field(
|
|
@@ -686,7 +697,7 @@ class BuildArguments(FindBuildArguments):
|
|
|
686
697
|
description='Record serialized app model of the built apps to the specified file. '
|
|
687
698
|
'Each line is a json string. Can expand placeholders @p',
|
|
688
699
|
validation_alias=AliasChoices('collect_app_info_filename', 'collect_app_info'),
|
|
689
|
-
default=None,
|
|
700
|
+
default=None, # type: ignore
|
|
690
701
|
exclude=True, # computed field is used
|
|
691
702
|
)
|
|
692
703
|
junitxml_filename: t.Optional[str] = field(
|
|
@@ -696,7 +707,7 @@ class BuildArguments(FindBuildArguments):
|
|
|
696
707
|
),
|
|
697
708
|
description='Path to the junitxml file to record the build results. Can expand placeholder @p',
|
|
698
709
|
validation_alias=AliasChoices('junitxml_filename', 'junitxml'),
|
|
699
|
-
default=None,
|
|
710
|
+
default=None, # type: ignore
|
|
700
711
|
exclude=True, # computed field is used
|
|
701
712
|
)
|
|
702
713
|
# used for expanding placeholders
|
|
@@ -753,7 +764,7 @@ class DumpManifestShaArguments(GlobalArguments):
|
|
|
753
764
|
required=True,
|
|
754
765
|
),
|
|
755
766
|
description='Path to the manifest files which contains the build test rules of the apps',
|
|
756
|
-
default=None,
|
|
767
|
+
default=None, # type: ignore
|
|
757
768
|
)
|
|
758
769
|
|
|
759
770
|
output: t.Optional[str] = field(
|
|
@@ -762,7 +773,7 @@ class DumpManifestShaArguments(GlobalArguments):
|
|
|
762
773
|
required=True,
|
|
763
774
|
),
|
|
764
775
|
description='Path to the output file to record the sha256 hash of the manifest rules',
|
|
765
|
-
default=None,
|
|
776
|
+
default=None, # type: ignore
|
|
766
777
|
)
|
|
767
778
|
|
|
768
779
|
def model_post_init(self, __context: Any) -> None:
|
idf_build_apps/finder.py
CHANGED
|
@@ -50,6 +50,7 @@ def _get_apps_from_path(
|
|
|
50
50
|
|
|
51
51
|
# for unknown ones, we keep them to the build stage to judge
|
|
52
52
|
if _app.build_status == BuildStatus.SKIPPED:
|
|
53
|
+
LOGGER.debug('=> Skipped. Reason: %s', _app.build_comment or 'Unknown')
|
|
53
54
|
return args.include_skipped_apps
|
|
54
55
|
|
|
55
56
|
return True
|
idf_build_apps/junit/utils.py
CHANGED
|
@@ -42,7 +42,7 @@ _name = Word(alphas, alphas + nums + '_')
|
|
|
42
42
|
# Define value, either a hex, int or a string
|
|
43
43
|
_hex_value = Combine(Literal('0x') + Word(hexnums) + Optional(_literal_suffix).suppress())('hex_value')
|
|
44
44
|
_str_value = QuotedString('"')('str_value')
|
|
45
|
-
_int_value = Word(nums)('int_value') + ~Char('.') + Optional(_literal_suffix)('literal_suffix')
|
|
45
|
+
_int_value = Combine(Optional('-') + Word(nums))('int_value') + ~Char('.') + Optional(_literal_suffix)('literal_suffix')
|
|
46
46
|
|
|
47
47
|
# Remove optional parenthesis around values
|
|
48
48
|
_value = Optional('(').suppress() + MatchFirst([_hex_value, _str_value, _int_value])('value') + Optional(')').suppress()
|
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,59 @@ 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
|
+
return provided.resolve()
|
|
97
|
+
|
|
98
|
+
rv = Path.cwd()
|
|
99
|
+
count = -1
|
|
100
|
+
while count < depth:
|
|
101
|
+
if str(rv) == rv.root:
|
|
102
|
+
break
|
|
103
|
+
|
|
104
|
+
fp = rv / filename
|
|
105
|
+
if fp.is_file():
|
|
106
|
+
print(f'Loading config file: {fp}')
|
|
107
|
+
return fp
|
|
108
|
+
|
|
109
|
+
rv = rv.parent
|
|
110
|
+
count += 1
|
|
111
|
+
|
|
112
|
+
return None
|
|
113
|
+
|
|
76
114
|
|
|
77
115
|
class PyprojectTomlConfigSettingsSource(TomlConfigSettingsSource):
|
|
78
116
|
"""
|
|
@@ -84,37 +122,16 @@ class PyprojectTomlConfigSettingsSource(TomlConfigSettingsSource):
|
|
|
84
122
|
settings_cls: Type[BaseSettings],
|
|
85
123
|
toml_file: Optional[Path] = None,
|
|
86
124
|
) -> None:
|
|
87
|
-
self.toml_file_path = self.
|
|
88
|
-
toml_file,
|
|
125
|
+
self.toml_file_path = self._pick_toml_file(
|
|
126
|
+
toml_file,
|
|
127
|
+
settings_cls.model_config.get('pyproject_toml_depth', sys.maxsize),
|
|
128
|
+
'pyproject.toml',
|
|
89
129
|
)
|
|
90
130
|
self.toml_table_header: Tuple[str, ...] = settings_cls.model_config.get(
|
|
91
|
-
'pyproject_toml_table_header',
|
|
131
|
+
'pyproject_toml_table_header',
|
|
132
|
+
('tool', 'idf-build-apps'),
|
|
92
133
|
)
|
|
93
134
|
self.toml_data = self._read_files(self.toml_file_path)
|
|
94
135
|
for key in self.toml_table_header:
|
|
95
136
|
self.toml_data = self.toml_data.get(key, {})
|
|
96
137
|
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.0
|
|
4
4
|
Summary: Tools for building ESP-IDF related apps.
|
|
5
5
|
Author-email: Fu Hanxi <fuhanxi@espressif.com>
|
|
6
6
|
Requires-Python: >=3.7
|
|
@@ -27,9 +27,10 @@ Requires-Dist: sphinx_copybutton ; extra == "doc"
|
|
|
27
27
|
Requires-Dist: myst-parser ; extra == "doc"
|
|
28
28
|
Requires-Dist: sphinxcontrib-mermaid ; extra == "doc"
|
|
29
29
|
Requires-Dist: sphinx-argparse ; extra == "doc"
|
|
30
|
+
Requires-Dist: sphinx-tabs ; extra == "doc"
|
|
30
31
|
Requires-Dist: pytest ; extra == "test"
|
|
31
32
|
Requires-Dist: pytest-cov ; extra == "test"
|
|
32
|
-
Project-URL: changelog, https://github.com/espressif/idf-build-apps/blob/
|
|
33
|
+
Project-URL: changelog, https://github.com/espressif/idf-build-apps/blob/main/CHANGELOG.md
|
|
33
34
|
Project-URL: documentation, https://docs.espressif.com/projects/idf-build-apps
|
|
34
35
|
Project-URL: homepage, https://github.com/espressif/idf-build-apps
|
|
35
36
|
Project-URL: repository, https://github.com/espressif/idf-build-apps
|
|
@@ -1,27 +1,28 @@
|
|
|
1
|
-
idf_build_apps/__init__.py,sha256=
|
|
1
|
+
idf_build_apps/__init__.py,sha256=VMMqqRp30Golk7dqGCARNL8mR9oZaz86HOXoySoXvIY,650
|
|
2
2
|
idf_build_apps/__main__.py,sha256=8E-5xHm2MlRun0L88XJleNh5U50dpE0Q1nK5KqomA7I,182
|
|
3
3
|
idf_build_apps/app.py,sha256=F-MKOsaz7cJ0H2wsEE4gpO4kkkEdkyFmIZBHDoM2qgs,37359
|
|
4
|
-
idf_build_apps/args.py,sha256=
|
|
4
|
+
idf_build_apps/args.py,sha256=7-rphv1hhbjJRfE_agBUyQbJaiUhsjsBo6C3eDmug2k,34101
|
|
5
5
|
idf_build_apps/autocompletions.py,sha256=g-bx0pzXoFKI0VQqftkHyGVWN6MLjuFOdozeuAf45yo,2138
|
|
6
6
|
idf_build_apps/constants.py,sha256=07ve2FtWuLBuc_6LFzbs1XncB1VNi9HJUqGjQQauRNM,3952
|
|
7
|
-
idf_build_apps/finder.py,sha256=
|
|
7
|
+
idf_build_apps/finder.py,sha256=hY6uSMB2s65MqMKIDBSHABOfa93mOLT7x5hlMxC43EQ,5794
|
|
8
8
|
idf_build_apps/log.py,sha256=pyvT7N4MWzGjIXph5mThQCGBiSt53RNPW0WrFfLr0Kw,2650
|
|
9
9
|
idf_build_apps/main.py,sha256=Z_hetbOavgCJZQPaP01_jx57fR1w0DefiFz0J2cCwp0,16498
|
|
10
|
+
idf_build_apps/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
10
11
|
idf_build_apps/session_args.py,sha256=2WDTy40IFAc0KQ57HaeBcYj_k10eUXRKkDOWLrFCaHY,2985
|
|
11
12
|
idf_build_apps/utils.py,sha256=s4D8P7QA17XcaCUQ_EoiNOW_VpU3cPQgiZVV9KQ8I30,10171
|
|
12
13
|
idf_build_apps/junit/__init__.py,sha256=IxvdaS6eSXp7kZxRuXqyZyGxuA_A1nOW1jF1HMi8Gns,231
|
|
13
14
|
idf_build_apps/junit/report.py,sha256=T7dVU3Sz5tqjfbcFW7wjsb65PDH6C2HFf73ePJqBhMs,6555
|
|
14
|
-
idf_build_apps/junit/utils.py,sha256=
|
|
15
|
+
idf_build_apps/junit/utils.py,sha256=NXZxQD4tdbSVKjKMNx1kO2H3IoEiysXkDoDjLEf1RO8,1303
|
|
15
16
|
idf_build_apps/manifest/__init__.py,sha256=Q2-cb3ngNjnl6_zWhUfzZZB10f_-Rv2JYNck3Lk7UkQ,133
|
|
16
17
|
idf_build_apps/manifest/if_parser.py,sha256=AAEyYPgcBWL2ToCmcvhx3fl8ebYdC5-LMvvDkYtWn8o,6546
|
|
17
18
|
idf_build_apps/manifest/manifest.py,sha256=6F6Nt93eaoBOHlGHZtv2hHT8Zw0HmJf0d_MESlgye6M,14478
|
|
18
|
-
idf_build_apps/manifest/soc_header.py,sha256=
|
|
19
|
+
idf_build_apps/manifest/soc_header.py,sha256=8vlsAjNsTxxb85RFJxVJTe11ealNQ8n5abUdNuC9ULo,4369
|
|
19
20
|
idf_build_apps/vendors/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
20
|
-
idf_build_apps/vendors/pydantic_sources.py,sha256=
|
|
21
|
+
idf_build_apps/vendors/pydantic_sources.py,sha256=2e-zA_aHe7NVXMoPKU_0Z9Lg9lw80TFWQ-2PZf10FMs,4419
|
|
21
22
|
idf_build_apps/yaml/__init__.py,sha256=W-3z5no07RQ6eYKGyOAPA8Z2CLiMPob8DD91I4URjrA,162
|
|
22
23
|
idf_build_apps/yaml/parser.py,sha256=b3LvogO6do-eJPRsYzT-8xk8AT2MnXpLCzQutJqyC7M,2128
|
|
23
|
-
idf_build_apps-2.
|
|
24
|
-
idf_build_apps-2.
|
|
25
|
-
idf_build_apps-2.
|
|
26
|
-
idf_build_apps-2.
|
|
27
|
-
idf_build_apps-2.
|
|
24
|
+
idf_build_apps-2.6.0.dist-info/entry_points.txt,sha256=3pVUirUEsb6jsDRikkQWNUt4hqLK2ci1HvW_Vf8b6uE,59
|
|
25
|
+
idf_build_apps-2.6.0.dist-info/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
|
|
26
|
+
idf_build_apps-2.6.0.dist-info/WHEEL,sha256=CpUCUxeHQbRN5UGRQHYRJorO5Af-Qy_fHMctcQ8DSGI,82
|
|
27
|
+
idf_build_apps-2.6.0.dist-info/METADATA,sha256=StRvId-xGrePTaC0FjO9O58mazLMSD0EZGrPDSOOxvs,4652
|
|
28
|
+
idf_build_apps-2.6.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|