idf-build-apps 2.11.2__py3-none-any.whl → 2.12.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 +1 -1
- idf_build_apps/app.py +110 -66
- idf_build_apps/args.py +42 -10
- idf_build_apps/finder.py +39 -55
- idf_build_apps/main.py +1 -2
- idf_build_apps/manifest/manifest.py +17 -5
- idf_build_apps/session_args.py +1 -2
- {idf_build_apps-2.11.2.dist-info → idf_build_apps-2.12.1.dist-info}/METADATA +1 -1
- {idf_build_apps-2.11.2.dist-info → idf_build_apps-2.12.1.dist-info}/RECORD +12 -12
- {idf_build_apps-2.11.2.dist-info → idf_build_apps-2.12.1.dist-info}/WHEEL +0 -0
- {idf_build_apps-2.11.2.dist-info → idf_build_apps-2.12.1.dist-info}/entry_points.txt +0 -0
- {idf_build_apps-2.11.2.dist-info → idf_build_apps-2.12.1.dist-info}/licenses/LICENSE +0 -0
idf_build_apps/__init__.py
CHANGED
idf_build_apps/app.py
CHANGED
|
@@ -95,6 +95,7 @@ class App(BaseModel):
|
|
|
95
95
|
|
|
96
96
|
_build_log_filename: t.Optional[str] = None
|
|
97
97
|
_size_json_filename: t.Optional[str] = None
|
|
98
|
+
size_json_extra_args: t.Optional[t.List[str]] = None
|
|
98
99
|
|
|
99
100
|
dry_run: bool = False
|
|
100
101
|
verbose: bool = False
|
|
@@ -105,15 +106,16 @@ class App(BaseModel):
|
|
|
105
106
|
# build_apps() related
|
|
106
107
|
index: t.Optional[int] = None
|
|
107
108
|
|
|
108
|
-
# build status related
|
|
109
109
|
build_status: BuildStatus = BuildStatus.UNKNOWN
|
|
110
110
|
build_comment: t.Optional[str] = None
|
|
111
|
+
test_comment: t.Optional[str] = None
|
|
111
112
|
|
|
112
113
|
_build_duration: float = 0
|
|
113
114
|
_build_timestamp: t.Optional[datetime] = None
|
|
114
115
|
|
|
115
116
|
__EQ_IGNORE_FIELDS__ = [
|
|
116
117
|
'build_comment',
|
|
118
|
+
'test_comment',
|
|
117
119
|
]
|
|
118
120
|
__EQ_TUNE_FIELDS__ = {
|
|
119
121
|
'app_dir': lambda x: (os.path.realpath(os.path.expanduser(x))),
|
|
@@ -324,8 +326,7 @@ class App(BaseModel):
|
|
|
324
326
|
# put the expanded variable files in a temporary directory
|
|
325
327
|
# will remove if the content is the same as the original one
|
|
326
328
|
expanded_dir = os.path.join(self.work_dir, 'expanded_sdkconfig_files', os.path.basename(self.build_dir))
|
|
327
|
-
|
|
328
|
-
os.makedirs(expanded_dir)
|
|
329
|
+
os.makedirs(expanded_dir, exist_ok=True)
|
|
329
330
|
|
|
330
331
|
for f in self.sdkconfig_defaults_candidates + ([self.sdkconfig_path] if self.sdkconfig_path else []):
|
|
331
332
|
# use filepath if abs/rel already point to itself
|
|
@@ -338,57 +339,47 @@ class App(BaseModel):
|
|
|
338
339
|
continue
|
|
339
340
|
|
|
340
341
|
expanded_fp = os.path.join(expanded_dir, os.path.basename(f))
|
|
341
|
-
with open(f) as fr:
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
if
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
):
|
|
380
|
-
LOGGER.debug(
|
|
381
|
-
'Copy target-specific sdkconfig file %s to %s', target_specific_file, expanded_dir
|
|
382
|
-
)
|
|
383
|
-
shutil.copy(target_specific_file, expanded_dir)
|
|
384
|
-
|
|
385
|
-
# remove if expanded folder is empty
|
|
386
|
-
try:
|
|
387
|
-
os.rmdir(expanded_dir)
|
|
388
|
-
except OSError:
|
|
389
|
-
pass
|
|
342
|
+
with open(f) as fr, open(expanded_fp, 'w') as fw:
|
|
343
|
+
for line in fr:
|
|
344
|
+
line = os.path.expandvars(line)
|
|
345
|
+
|
|
346
|
+
m = self.SDKCONFIG_LINE_REGEX.match(line)
|
|
347
|
+
if m:
|
|
348
|
+
key, value = m.group(1), m.group(2)
|
|
349
|
+
if key == 'CONFIG_IDF_TARGET':
|
|
350
|
+
sdkconfig_files_defined_target = value
|
|
351
|
+
|
|
352
|
+
if isinstance(self, CMakeApp):
|
|
353
|
+
if key in self.SDKCONFIG_TEST_OPTS:
|
|
354
|
+
self.cmake_vars[key] = value
|
|
355
|
+
continue
|
|
356
|
+
if key in self.SDKCONFIG_IGNORE_OPTS:
|
|
357
|
+
continue
|
|
358
|
+
|
|
359
|
+
fw.write(line)
|
|
360
|
+
|
|
361
|
+
with open(f) as fr, open(expanded_fp) as new_fr:
|
|
362
|
+
if fr.read() == new_fr.read():
|
|
363
|
+
LOGGER.debug('Use sdkconfig file %s', f)
|
|
364
|
+
try:
|
|
365
|
+
os.unlink(expanded_fp)
|
|
366
|
+
except OSError:
|
|
367
|
+
LOGGER.debug('Failed to remove file %s', expanded_fp)
|
|
368
|
+
real_sdkconfig_files.append(f)
|
|
369
|
+
else:
|
|
370
|
+
LOGGER.debug('Expand sdkconfig file %s to %s', f, expanded_fp)
|
|
371
|
+
real_sdkconfig_files.append(expanded_fp)
|
|
372
|
+
# copy the related target-specific sdkconfig files
|
|
373
|
+
par_dir = os.path.abspath(os.path.join(f, '..'))
|
|
374
|
+
for target_specific_file in (
|
|
375
|
+
os.path.join(par_dir, str(p))
|
|
376
|
+
for p in Path(par_dir).glob(os.path.basename(f) + f'.{self.target}')
|
|
377
|
+
):
|
|
378
|
+
LOGGER.debug('Copy target-specific sdkconfig file %s to %s', target_specific_file, expanded_dir)
|
|
379
|
+
shutil.copy(target_specific_file, expanded_dir)
|
|
390
380
|
|
|
391
381
|
try:
|
|
382
|
+
os.rmdir(expanded_dir)
|
|
392
383
|
os.rmdir(os.path.join(self.work_dir, 'expanded_sdkconfig_files'))
|
|
393
384
|
except OSError:
|
|
394
385
|
pass
|
|
@@ -428,14 +419,14 @@ class App(BaseModel):
|
|
|
428
419
|
|
|
429
420
|
@property
|
|
430
421
|
def supported_targets(self) -> t.List[str]:
|
|
422
|
+
if self.sdkconfig_files_defined_idf_target:
|
|
423
|
+
return [self.sdkconfig_files_defined_idf_target]
|
|
424
|
+
|
|
431
425
|
if self.MANIFEST:
|
|
432
426
|
return self.MANIFEST.enable_build_targets(
|
|
433
427
|
self.app_dir, self.sdkconfig_files_defined_idf_target, self.config_name
|
|
434
428
|
)
|
|
435
429
|
|
|
436
|
-
if self.sdkconfig_files_defined_idf_target:
|
|
437
|
-
return [self.sdkconfig_files_defined_idf_target]
|
|
438
|
-
|
|
439
430
|
return DEFAULT_BUILD_TARGETS.get()
|
|
440
431
|
|
|
441
432
|
@property
|
|
@@ -656,11 +647,10 @@ class App(BaseModel):
|
|
|
656
647
|
[
|
|
657
648
|
sys.executable,
|
|
658
649
|
str(IDF_SIZE_PY),
|
|
659
|
-
|
|
660
|
-
+ (['--json'] if IDF_VERSION < Version('5.1') else ['--format', 'json'])
|
|
661
|
-
+ [
|
|
650
|
+
*(['--json'] if IDF_VERSION < Version('5.1') else ['--format', 'json']),
|
|
662
651
|
'-o',
|
|
663
652
|
self.size_json_path,
|
|
653
|
+
*(self.size_json_extra_args or []),
|
|
664
654
|
map_file,
|
|
665
655
|
],
|
|
666
656
|
check=True,
|
|
@@ -668,14 +658,13 @@ class App(BaseModel):
|
|
|
668
658
|
else:
|
|
669
659
|
with open(self.size_json_path, 'w') as fw:
|
|
670
660
|
subprocess_run(
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
),
|
|
661
|
+
[
|
|
662
|
+
sys.executable,
|
|
663
|
+
str(IDF_SIZE_PY),
|
|
664
|
+
'--json',
|
|
665
|
+
*(self.size_json_extra_args or []),
|
|
666
|
+
map_file,
|
|
667
|
+
],
|
|
679
668
|
log_terminal=False,
|
|
680
669
|
log_fs=fw,
|
|
681
670
|
check=True,
|
|
@@ -735,9 +724,35 @@ class App(BaseModel):
|
|
|
735
724
|
modified_components: t.Optional[t.List[str]] = None,
|
|
736
725
|
modified_files: t.Optional[t.List[str]] = None,
|
|
737
726
|
) -> None:
|
|
727
|
+
"""Check if this app should be built based on the modified files and components."""
|
|
738
728
|
if self.build_status != BuildStatus.UNKNOWN:
|
|
739
729
|
return
|
|
740
730
|
|
|
731
|
+
if self.target not in self.supported_targets:
|
|
732
|
+
# default error message
|
|
733
|
+
self.build_comment = (
|
|
734
|
+
f'Target {self.target} not in default build targets {",".join(DEFAULT_BUILD_TARGETS.get())}'
|
|
735
|
+
)
|
|
736
|
+
|
|
737
|
+
if self.MANIFEST:
|
|
738
|
+
rule = self.MANIFEST.most_suitable_rule(self.app_dir)
|
|
739
|
+
|
|
740
|
+
# disable > enable
|
|
741
|
+
for clause in rule.disable:
|
|
742
|
+
if clause.get_value(self.target, self.config_name or ''):
|
|
743
|
+
self.build_comment = f'Disabled by manifest rule: {clause}'
|
|
744
|
+
break
|
|
745
|
+
else:
|
|
746
|
+
# Check if it's not enabled by manifest rules
|
|
747
|
+
if rule.enable:
|
|
748
|
+
# Has enable rules but target not in enabled targets
|
|
749
|
+
self.build_comment = 'Not enabled by manifest rules:\n'
|
|
750
|
+
self.build_comment += '\n'.join(f'- {clause}' for clause in rule.enable)
|
|
751
|
+
|
|
752
|
+
self.build_status = BuildStatus.DISABLED
|
|
753
|
+
self._checked_should_build = True
|
|
754
|
+
return
|
|
755
|
+
|
|
741
756
|
if not check_app_dependencies:
|
|
742
757
|
self.build_status = BuildStatus.SHOULD_BE_BUILT
|
|
743
758
|
self._checked_should_build = True
|
|
@@ -804,6 +819,35 @@ class App(BaseModel):
|
|
|
804
819
|
self.build_comment = 'current build does not modify any components or files required by this app'
|
|
805
820
|
self._checked_should_build = True
|
|
806
821
|
|
|
822
|
+
def check_should_test(self) -> None:
|
|
823
|
+
"""Check if testing is disabled for this app and set test_disable_reason."""
|
|
824
|
+
if not self.MANIFEST:
|
|
825
|
+
return
|
|
826
|
+
|
|
827
|
+
rule = self.MANIFEST.most_suitable_rule(self.app_dir)
|
|
828
|
+
|
|
829
|
+
# Check if testing is enabled for this target
|
|
830
|
+
if self.target not in self.verified_targets:
|
|
831
|
+
# default error message
|
|
832
|
+
self.test_comment = f'Target {self.target} not in verified targets {",".join(self.verified_targets)}'
|
|
833
|
+
|
|
834
|
+
# disable_test > disable > enable
|
|
835
|
+
for clause in rule.disable_test:
|
|
836
|
+
if clause.get_value(self.target, self.config_name or ''):
|
|
837
|
+
self.test_comment = f'Disabled by manifest rule: {clause}'
|
|
838
|
+
return
|
|
839
|
+
|
|
840
|
+
# Check if disabled by general disable rules
|
|
841
|
+
for clause in rule.disable:
|
|
842
|
+
if clause.get_value(self.target, self.config_name or ''):
|
|
843
|
+
self.test_comment = f'Disabled by manifest rule: {clause}'
|
|
844
|
+
return
|
|
845
|
+
|
|
846
|
+
# If not explicitly disabled but not in enabled targets
|
|
847
|
+
if rule.enable:
|
|
848
|
+
self.test_comment = 'Not enabled by manifest rules:\n'
|
|
849
|
+
self.test_comment += '\n'.join(f'- {clause}' for clause in rule.enable)
|
|
850
|
+
|
|
807
851
|
|
|
808
852
|
class MakeApp(App):
|
|
809
853
|
MAKE_PROJECT_LINE: t.ClassVar[str] = r'include $(IDF_PATH)/make/project.mk'
|
idf_build_apps/args.py
CHANGED
|
@@ -240,10 +240,20 @@ class DependencyDrivenBuildArguments(GlobalArguments):
|
|
|
240
240
|
validate_method=[ValidateMethod.TO_LIST],
|
|
241
241
|
nargs='+',
|
|
242
242
|
),
|
|
243
|
-
description='space-separated list of file patterns to search for the manifest files. '
|
|
243
|
+
description='space-separated list of file glob patterns to search for the manifest files. '
|
|
244
244
|
'The matched files will be loaded as the manifest files.',
|
|
245
245
|
default=None, # type: ignore
|
|
246
246
|
)
|
|
247
|
+
manifest_exclude_regexes: t.Optional[t.List[str]] = field(
|
|
248
|
+
FieldMetadata(
|
|
249
|
+
validate_method=[ValidateMethod.TO_LIST],
|
|
250
|
+
nargs='+',
|
|
251
|
+
),
|
|
252
|
+
description='space-separated list of regex to exclude when searching for manifest files. '
|
|
253
|
+
'Files matching these patterns will be ignored. '
|
|
254
|
+
'By default excludes files under "managed_components" directories.',
|
|
255
|
+
default=['/managed_components/'], # type: ignore
|
|
256
|
+
)
|
|
247
257
|
manifest_rootpath: str = field(
|
|
248
258
|
None,
|
|
249
259
|
description='Root path to resolve the relative paths defined in the manifest files. '
|
|
@@ -337,6 +347,22 @@ class DependencyDrivenBuildArguments(GlobalArguments):
|
|
|
337
347
|
for pat in [to_absolute_path(p, self.manifest_rootpath) for p in self.manifest_filepatterns]:
|
|
338
348
|
matched_paths.update(glob.glob(str(pat), recursive=True))
|
|
339
349
|
|
|
350
|
+
exclude_regexes = {re.compile(regex) for regex in self.manifest_exclude_regexes or []}
|
|
351
|
+
|
|
352
|
+
# Filter out files matching excluded patterns
|
|
353
|
+
if matched_paths:
|
|
354
|
+
filtered_paths = set()
|
|
355
|
+
for path in matched_paths:
|
|
356
|
+
posix_path = Path(path).as_posix()
|
|
357
|
+
for regex in exclude_regexes:
|
|
358
|
+
if regex.search(posix_path):
|
|
359
|
+
LOGGER.debug(f'Excluding manifest file {path} due to excluded regex match')
|
|
360
|
+
break
|
|
361
|
+
else:
|
|
362
|
+
filtered_paths.add(path)
|
|
363
|
+
|
|
364
|
+
matched_paths = filtered_paths
|
|
365
|
+
|
|
340
366
|
if matched_paths:
|
|
341
367
|
if self.manifest_files:
|
|
342
368
|
self.manifest_files.extend(matched_paths)
|
|
@@ -482,6 +508,13 @@ class FindBuildArguments(DependencyDrivenBuildArguments):
|
|
|
482
508
|
validation_alias=AliasChoices('size_json_filename', 'size_file'),
|
|
483
509
|
default=None, # type: ignore
|
|
484
510
|
)
|
|
511
|
+
size_json_extra_args: t.Optional[t.List[str]] = field(
|
|
512
|
+
FieldMetadata(
|
|
513
|
+
validate_method=[ValidateMethod.TO_LIST],
|
|
514
|
+
),
|
|
515
|
+
description='Additional arguments to pass to esp_idf_size tool',
|
|
516
|
+
default=None, # type: ignore
|
|
517
|
+
)
|
|
485
518
|
config_rules: t.Optional[t.List[str]] = field(
|
|
486
519
|
FieldMetadata(
|
|
487
520
|
validate_method=[ValidateMethod.TO_LIST],
|
|
@@ -607,7 +640,7 @@ class FindBuildArguments(DependencyDrivenBuildArguments):
|
|
|
607
640
|
elif self.enable_preview_targets:
|
|
608
641
|
self.default_build_targets = deepcopy(ALL_TARGETS)
|
|
609
642
|
LOGGER.info('Overriding default build targets to %s', self.default_build_targets)
|
|
610
|
-
DEFAULT_BUILD_TARGETS.set(self.default_build_targets)
|
|
643
|
+
DEFAULT_BUILD_TARGETS.set(self.default_build_targets)
|
|
611
644
|
|
|
612
645
|
if self.disable_targets and DEFAULT_BUILD_TARGETS.get():
|
|
613
646
|
LOGGER.info('Disable targets: %s', self.disable_targets)
|
|
@@ -823,20 +856,19 @@ class BuildArguments(FindBuildArguments):
|
|
|
823
856
|
def model_post_init(self, __context: Any) -> None:
|
|
824
857
|
super().model_post_init(__context)
|
|
825
858
|
|
|
826
|
-
|
|
859
|
+
patterns = []
|
|
827
860
|
if self.ignore_warning_strs:
|
|
828
|
-
|
|
829
|
-
|
|
861
|
+
patterns.extend(self.ignore_warning_strs)
|
|
862
|
+
|
|
830
863
|
if self.ignore_warning_files:
|
|
831
864
|
for f in self.ignore_warning_files:
|
|
832
865
|
if isinstance(f, str):
|
|
833
866
|
with open(f) as fr:
|
|
834
|
-
for
|
|
835
|
-
ignore_warnings_regexes.append(re.compile(s.strip()))
|
|
867
|
+
patterns.extend(line.strip() for line in fr)
|
|
836
868
|
else:
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
App.IGNORE_WARNS_REGEXES =
|
|
869
|
+
patterns.extend(f)
|
|
870
|
+
|
|
871
|
+
App.IGNORE_WARNS_REGEXES = [re.compile(p.strip()) for p in patterns if p.strip()]
|
|
840
872
|
|
|
841
873
|
@computed_field # type: ignore
|
|
842
874
|
@property
|
idf_build_apps/finder.py
CHANGED
|
@@ -18,7 +18,6 @@ from .args import FindArguments
|
|
|
18
18
|
from .constants import (
|
|
19
19
|
BuildStatus,
|
|
20
20
|
)
|
|
21
|
-
from .manifest.manifest import DEFAULT_BUILD_TARGETS
|
|
22
21
|
from .utils import (
|
|
23
22
|
config_rules_from_str,
|
|
24
23
|
to_absolute_path,
|
|
@@ -34,38 +33,6 @@ def _get_apps_from_path(
|
|
|
34
33
|
app_cls: t.Type[App] = CMakeApp,
|
|
35
34
|
args: FindArguments,
|
|
36
35
|
) -> t.List[App]:
|
|
37
|
-
def _validate_app(_app: App) -> bool:
|
|
38
|
-
if target not in _app.supported_targets:
|
|
39
|
-
LOGGER.debug('=> Ignored. %s only supports targets: %s', _app, ', '.join(_app.supported_targets))
|
|
40
|
-
_app.build_status = BuildStatus.DISABLED
|
|
41
|
-
return args.include_disabled_apps
|
|
42
|
-
|
|
43
|
-
if target == 'all' and _app.target not in DEFAULT_BUILD_TARGETS.get():
|
|
44
|
-
LOGGER.debug(
|
|
45
|
-
'=> Ignored. %s is not in the default build targets: %s', _app.target, DEFAULT_BUILD_TARGETS.get()
|
|
46
|
-
)
|
|
47
|
-
_app.build_status = BuildStatus.DISABLED
|
|
48
|
-
return args.include_disabled_apps
|
|
49
|
-
elif _app.target != target:
|
|
50
|
-
LOGGER.debug('=> Ignored. %s is not for target %s', _app, target)
|
|
51
|
-
_app.build_status = BuildStatus.DISABLED
|
|
52
|
-
return args.include_disabled_apps
|
|
53
|
-
|
|
54
|
-
_app.check_should_build(
|
|
55
|
-
manifest_rootpath=args.manifest_rootpath,
|
|
56
|
-
modified_manifest_rules_folders=args.modified_manifest_rules_folders,
|
|
57
|
-
modified_components=args.modified_components,
|
|
58
|
-
modified_files=args.modified_files,
|
|
59
|
-
check_app_dependencies=args.dependency_driven_build_enabled,
|
|
60
|
-
)
|
|
61
|
-
|
|
62
|
-
# for unknown ones, we keep them to the build stage to judge
|
|
63
|
-
if _app.build_status == BuildStatus.SKIPPED:
|
|
64
|
-
LOGGER.debug('=> Skipped. Reason: %s', _app.build_comment or 'Unknown')
|
|
65
|
-
return args.include_skipped_apps
|
|
66
|
-
|
|
67
|
-
return True
|
|
68
|
-
|
|
69
36
|
if not app_cls.is_app(path):
|
|
70
37
|
LOGGER.debug('Skipping. %s is not an app', path)
|
|
71
38
|
return []
|
|
@@ -73,8 +40,10 @@ def _get_apps_from_path(
|
|
|
73
40
|
config_rules = config_rules_from_str(args.config_rules)
|
|
74
41
|
|
|
75
42
|
apps = []
|
|
43
|
+
app_configs: t.List[t.Tuple[t.Optional[str], str]] = [] # List of (sdkconfig_path, config_name) tuples
|
|
76
44
|
default_config_name = ''
|
|
77
45
|
sdkconfig_paths_matched = False
|
|
46
|
+
|
|
78
47
|
for rule in config_rules:
|
|
79
48
|
if not rule.file_name:
|
|
80
49
|
default_config_name = rule.config_name
|
|
@@ -99,45 +68,60 @@ def _get_apps_from_path(
|
|
|
99
68
|
assert groups
|
|
100
69
|
config_name = groups.group(1)
|
|
101
70
|
|
|
102
|
-
|
|
103
|
-
path,
|
|
104
|
-
target,
|
|
105
|
-
sdkconfig_path=sdkconfig_path,
|
|
106
|
-
config_name=config_name,
|
|
107
|
-
work_dir=args.work_dir,
|
|
108
|
-
build_dir=args.build_dir,
|
|
109
|
-
build_log_filename=args.build_log_filename,
|
|
110
|
-
size_json_filename=args.size_json_filename,
|
|
111
|
-
check_warnings=args.check_warnings,
|
|
112
|
-
sdkconfig_defaults_str=args.sdkconfig_defaults,
|
|
113
|
-
)
|
|
114
|
-
if _validate_app(app):
|
|
115
|
-
LOGGER.debug('Found app: %s', app)
|
|
116
|
-
apps.append(app)
|
|
117
|
-
|
|
118
|
-
LOGGER.debug('') # add one empty line for separating different finds
|
|
71
|
+
app_configs.append((sdkconfig_path, config_name))
|
|
119
72
|
|
|
120
73
|
# no config rules matched, use default app
|
|
121
74
|
if not sdkconfig_paths_matched:
|
|
75
|
+
app_configs.append((None, default_config_name))
|
|
76
|
+
|
|
77
|
+
# Create, validate, and add all apps
|
|
78
|
+
for p, n in app_configs:
|
|
122
79
|
app = app_cls(
|
|
123
80
|
path,
|
|
124
81
|
target,
|
|
125
|
-
sdkconfig_path=
|
|
126
|
-
config_name=
|
|
82
|
+
sdkconfig_path=p,
|
|
83
|
+
config_name=n,
|
|
127
84
|
work_dir=args.work_dir,
|
|
128
85
|
build_dir=args.build_dir,
|
|
129
86
|
build_log_filename=args.build_log_filename,
|
|
130
87
|
size_json_filename=args.size_json_filename,
|
|
88
|
+
size_json_extra_args=args.size_json_extra_args,
|
|
131
89
|
check_warnings=args.check_warnings,
|
|
132
90
|
sdkconfig_defaults_str=args.sdkconfig_defaults,
|
|
133
91
|
)
|
|
134
92
|
|
|
135
|
-
if
|
|
93
|
+
if app.sdkconfig_files_defined_idf_target and app.target != app.sdkconfig_files_defined_idf_target:
|
|
94
|
+
LOGGER.debug(
|
|
95
|
+
'Project %s with config %s defined CONFIG_IDF_TARGET=%s, Ignoring target %s',
|
|
96
|
+
app.app_dir,
|
|
97
|
+
app.config_name or 'default',
|
|
98
|
+
app.sdkconfig_files_defined_idf_target,
|
|
99
|
+
target,
|
|
100
|
+
)
|
|
101
|
+
continue
|
|
102
|
+
|
|
103
|
+
app.check_should_build(
|
|
104
|
+
manifest_rootpath=args.manifest_rootpath,
|
|
105
|
+
modified_manifest_rules_folders=args.modified_manifest_rules_folders,
|
|
106
|
+
modified_components=args.modified_components,
|
|
107
|
+
modified_files=args.modified_files,
|
|
108
|
+
check_app_dependencies=args.dependency_driven_build_enabled,
|
|
109
|
+
)
|
|
110
|
+
app.check_should_test()
|
|
111
|
+
|
|
112
|
+
if app.build_status == BuildStatus.DISABLED:
|
|
113
|
+
LOGGER.debug('=> Disabled. Reason: %s', app.build_comment or 'Unknown')
|
|
114
|
+
should_include = args.include_disabled_apps
|
|
115
|
+
elif app.build_status == BuildStatus.SKIPPED:
|
|
116
|
+
LOGGER.debug('=> Skipped. Reason: %s', app.build_comment or 'Unknown')
|
|
117
|
+
should_include = args.include_skipped_apps
|
|
118
|
+
else:
|
|
119
|
+
should_include = True
|
|
120
|
+
|
|
121
|
+
if should_include:
|
|
136
122
|
LOGGER.debug('Found app: %s', app)
|
|
137
123
|
apps.append(app)
|
|
138
124
|
|
|
139
|
-
LOGGER.debug('') # add one empty line for separating different finds
|
|
140
|
-
|
|
141
125
|
return sorted(apps)
|
|
142
126
|
|
|
143
127
|
|
idf_build_apps/main.py
CHANGED
|
@@ -408,8 +408,7 @@ def main():
|
|
|
408
408
|
os.makedirs(os.path.dirname(os.path.realpath(arguments.output)), exist_ok=True)
|
|
409
409
|
with open(arguments.output, 'w') as fw:
|
|
410
410
|
if arguments.output_format == 'raw':
|
|
411
|
-
for app in apps
|
|
412
|
-
fw.write(app.to_json() + '\n')
|
|
411
|
+
fw.writelines(app.to_json() + '\n' for app in apps)
|
|
413
412
|
elif arguments.output_format == 'json':
|
|
414
413
|
fw.write(json.dumps([app.model_dump() for app in apps], indent=2))
|
|
415
414
|
else:
|
|
@@ -5,6 +5,7 @@ import logging
|
|
|
5
5
|
import os
|
|
6
6
|
import typing as t
|
|
7
7
|
import warnings
|
|
8
|
+
from functools import lru_cache
|
|
8
9
|
from hashlib import sha512
|
|
9
10
|
|
|
10
11
|
from esp_bool_parser import BoolStmt, parse_bool_expr
|
|
@@ -60,6 +61,14 @@ class IfClause:
|
|
|
60
61
|
f' reason: lack of ci runners'
|
|
61
62
|
)
|
|
62
63
|
|
|
64
|
+
def __str__(self):
|
|
65
|
+
s = self._stmt
|
|
66
|
+
if self.temporary:
|
|
67
|
+
s += ' (temporary)'
|
|
68
|
+
if self.reason:
|
|
69
|
+
s += f' (reason: {self.reason})'
|
|
70
|
+
return s
|
|
71
|
+
|
|
63
72
|
def __repr__(self):
|
|
64
73
|
return f'IfClause(stmt={self._stmt!r}, temporary={self.temporary!r}, reason={self.reason!r})'
|
|
65
74
|
|
|
@@ -95,7 +104,7 @@ def _getattr_default_build_targets(name: str) -> t.Any:
|
|
|
95
104
|
warnings.warn(
|
|
96
105
|
'FolderRule.DEFAULT_BUILD_TARGETS is deprecated. Use DEFAULT_BUILD_TARGETS.get() directly.',
|
|
97
106
|
DeprecationWarning,
|
|
98
|
-
stacklevel=
|
|
107
|
+
stacklevel=3,
|
|
99
108
|
)
|
|
100
109
|
return DEFAULT_BUILD_TARGETS.get()
|
|
101
110
|
return None
|
|
@@ -106,7 +115,7 @@ def _setattr_default_build_targets(name: str, value: t.Any) -> bool:
|
|
|
106
115
|
warnings.warn(
|
|
107
116
|
'FolderRule.DEFAULT_BUILD_TARGETS is deprecated. Use DEFAULT_BUILD_TARGETS.set() directly.',
|
|
108
117
|
DeprecationWarning,
|
|
109
|
-
stacklevel=
|
|
118
|
+
stacklevel=3,
|
|
110
119
|
)
|
|
111
120
|
if not isinstance(value, list):
|
|
112
121
|
raise TypeError('Default build targets must be a list')
|
|
@@ -244,6 +253,7 @@ class FolderRule(metaclass=_FolderRuleMeta):
|
|
|
244
253
|
def by_manifest_file(self) -> t.Optional[str]:
|
|
245
254
|
return self._manifest_filepath
|
|
246
255
|
|
|
256
|
+
@lru_cache(None)
|
|
247
257
|
def _enable_build(self, target: str, config_name: str) -> bool:
|
|
248
258
|
if self.enable:
|
|
249
259
|
res = False
|
|
@@ -252,7 +262,7 @@ class FolderRule(metaclass=_FolderRuleMeta):
|
|
|
252
262
|
res = True
|
|
253
263
|
break
|
|
254
264
|
else:
|
|
255
|
-
res = target in
|
|
265
|
+
res = target in DEFAULT_BUILD_TARGETS.get()
|
|
256
266
|
|
|
257
267
|
if self.disable:
|
|
258
268
|
for clause in self.disable:
|
|
@@ -262,6 +272,7 @@ class FolderRule(metaclass=_FolderRuleMeta):
|
|
|
262
272
|
|
|
263
273
|
return res
|
|
264
274
|
|
|
275
|
+
@lru_cache(None)
|
|
265
276
|
def _enable_test(
|
|
266
277
|
self, target: str, default_sdkconfig_target: t.Optional[str] = None, config_name: t.Optional[str] = None
|
|
267
278
|
) -> bool:
|
|
@@ -275,6 +286,7 @@ class FolderRule(metaclass=_FolderRuleMeta):
|
|
|
275
286
|
|
|
276
287
|
return res
|
|
277
288
|
|
|
289
|
+
@lru_cache(None)
|
|
278
290
|
def enable_build_targets(
|
|
279
291
|
self, default_sdkconfig_target: t.Optional[str] = None, config_name: t.Optional[str] = None
|
|
280
292
|
) -> t.List[str]:
|
|
@@ -301,6 +313,7 @@ class FolderRule(metaclass=_FolderRuleMeta):
|
|
|
301
313
|
|
|
302
314
|
return sorted(res)
|
|
303
315
|
|
|
316
|
+
@lru_cache(None)
|
|
304
317
|
def enable_test_targets(
|
|
305
318
|
self, default_sdkconfig_target: t.Optional[str] = None, config_name: t.Optional[str] = None
|
|
306
319
|
) -> t.List[str]:
|
|
@@ -402,8 +415,7 @@ class Manifest:
|
|
|
402
415
|
:return: None
|
|
403
416
|
"""
|
|
404
417
|
with open(sha_filepath, 'w') as fw:
|
|
405
|
-
for rule in self.rules
|
|
406
|
-
fw.write(f'{os.path.relpath(rule.folder, self._root_path)}:{rule.sha}\n')
|
|
418
|
+
fw.writelines(f'{os.path.relpath(rule.folder, self._root_path)}:{rule.sha}\n' for rule in self.rules)
|
|
407
419
|
|
|
408
420
|
def diff_sha_with_filepath(self, sha_filepath: str, use_abspath: bool = False) -> t.Set[str]:
|
|
409
421
|
"""
|
idf_build_apps/session_args.py
CHANGED
|
@@ -70,6 +70,5 @@ class SessionArgs:
|
|
|
70
70
|
return None
|
|
71
71
|
f_path = os.path.join(self.workdir, 'override-result.sdkconfig')
|
|
72
72
|
with open(f_path, 'w+') as f:
|
|
73
|
-
for key, value in override_sdkconfig_merged_items.items()
|
|
74
|
-
f.write(f'{key}={value}\n')
|
|
73
|
+
f.writelines(f'{key}={value}\n' for key, value in override_sdkconfig_merged_items.items())
|
|
75
74
|
return f_path
|
|
@@ -1,27 +1,27 @@
|
|
|
1
|
-
idf_build_apps/__init__.py,sha256=
|
|
1
|
+
idf_build_apps/__init__.py,sha256=jLG3VCE5fMIO-Zpaj5NKV5VTXqzNr69_PBXu7bwh5gc,711
|
|
2
2
|
idf_build_apps/__main__.py,sha256=pT6OsFQRjCw39Jg43HAeGKzq8h5E_0m7kHDE2QMqDe0,182
|
|
3
|
-
idf_build_apps/app.py,sha256
|
|
4
|
-
idf_build_apps/args.py,sha256=
|
|
3
|
+
idf_build_apps/app.py,sha256=-pP1vCPGYePFr9nO-Y00WfQ4Bg5DWyHlH_gWDtvAZio,39181
|
|
4
|
+
idf_build_apps/args.py,sha256=m1tJl75P3yuDIaxQpg4bL8UIe2j_R1tNvQW_vpyR1AU,40099
|
|
5
5
|
idf_build_apps/autocompletions.py,sha256=2fZQxzgZ21ie_2uk-B-7-xWYCChfOSgRFRYb7I2Onfo,2143
|
|
6
6
|
idf_build_apps/constants.py,sha256=2iwLPZRhSQcn1v4RAcOJnHbqp1fDTp6A1gHaxn5ciTE,2166
|
|
7
|
-
idf_build_apps/finder.py,sha256=
|
|
7
|
+
idf_build_apps/finder.py,sha256=gpOcpGrzAGiBVRCgKQ_YW22_OUJv-D-hMApuE-tPhVQ,5644
|
|
8
8
|
idf_build_apps/log.py,sha256=15sSQhv9dJsHShDR2KgFGFp8ByjV0HogLr1X1lHYqGs,3899
|
|
9
|
-
idf_build_apps/main.py,sha256=
|
|
9
|
+
idf_build_apps/main.py,sha256=P_TsUA2s048qcRb-wVngF-zqNjH_NEYrQsAYKB1GHmU,17960
|
|
10
10
|
idf_build_apps/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
11
|
-
idf_build_apps/session_args.py,sha256=
|
|
11
|
+
idf_build_apps/session_args.py,sha256=1B7e3M9_eKdQezGNXaocqCq7iE4MOxpYJkfanCfdkDE,2973
|
|
12
12
|
idf_build_apps/utils.py,sha256=cQJ5N-53vrASa4d8WW0AQCPJzendArXyU3kB5Vx-AH8,10880
|
|
13
13
|
idf_build_apps/junit/__init__.py,sha256=ljILW1rfeBAIlwZIw8jstYrVbugErlmCYzSzJwNFC2I,231
|
|
14
14
|
idf_build_apps/junit/report.py,sha256=yzt5SiJEA_AUlw2Ld23J7enYlfDluvmKAcCnAM8ccqE,6565
|
|
15
15
|
idf_build_apps/junit/utils.py,sha256=idBrLgsz6Co2QUQqq1AiyzRHnqbJf_EoykEAxCkjHZw,1303
|
|
16
16
|
idf_build_apps/manifest/__init__.py,sha256=CP4_LSkh7sb_DsWLSzqkSZ3UojyVdM10bX9avlmn2pg,479
|
|
17
|
-
idf_build_apps/manifest/manifest.py,sha256=
|
|
17
|
+
idf_build_apps/manifest/manifest.py,sha256=i8bXxyHeIFxYN5Z1l0dNNBFdgP7SKl3t0TCVqhlF0Lo,18051
|
|
18
18
|
idf_build_apps/manifest/soc_header.py,sha256=_F6H5-HP6ateAqKUGlRGH-SUtQ8NJ1RI0hBeCFvsDYA,172
|
|
19
19
|
idf_build_apps/vendors/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
20
20
|
idf_build_apps/vendors/pydantic_sources.py,sha256=cxSIPRc3eI5peVMhDxwf58YaGhuG4SCwPRVX2znFEek,4553
|
|
21
21
|
idf_build_apps/yaml/__init__.py,sha256=R6pYasVsD31maeZ4dWRZnS10hwzM7gXdnfzDsOIRJ-4,167
|
|
22
22
|
idf_build_apps/yaml/parser.py,sha256=IhY7rCWXOxrzzgEiKipTdPs_8yXDf8JZr-sMewV1pk8,2133
|
|
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.
|
|
23
|
+
idf_build_apps-2.12.1.dist-info/entry_points.txt,sha256=3pVUirUEsb6jsDRikkQWNUt4hqLK2ci1HvW_Vf8b6uE,59
|
|
24
|
+
idf_build_apps-2.12.1.dist-info/licenses/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
|
|
25
|
+
idf_build_apps-2.12.1.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
|
|
26
|
+
idf_build_apps-2.12.1.dist-info/METADATA,sha256=9QsZhWmo-I-RNRwcOit0XozghfY3vxiPusnDTDEK3WQ,4795
|
|
27
|
+
idf_build_apps-2.12.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|