idf-build-apps 2.4.1__py3-none-any.whl → 2.4.2__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 +65 -35
- idf_build_apps/constants.py +6 -5
- idf_build_apps/finder.py +4 -2
- idf_build_apps/junit/report.py +10 -6
- idf_build_apps/junit/utils.py +2 -2
- idf_build_apps/main.py +83 -47
- idf_build_apps/manifest/soc_header.py +18 -14
- {idf_build_apps-2.4.1.dist-info → idf_build_apps-2.4.2.dist-info}/METADATA +1 -1
- {idf_build_apps-2.4.1.dist-info → idf_build_apps-2.4.2.dist-info}/RECORD +13 -13
- {idf_build_apps-2.4.1.dist-info → idf_build_apps-2.4.2.dist-info}/LICENSE +0 -0
- {idf_build_apps-2.4.1.dist-info → idf_build_apps-2.4.2.dist-info}/WHEEL +0 -0
- {idf_build_apps-2.4.1.dist-info → idf_build_apps-2.4.2.dist-info}/entry_points.txt +0 -0
idf_build_apps/__init__.py
CHANGED
idf_build_apps/app.py
CHANGED
|
@@ -10,9 +10,7 @@ import re
|
|
|
10
10
|
import shutil
|
|
11
11
|
import sys
|
|
12
12
|
import typing as t
|
|
13
|
-
from datetime import
|
|
14
|
-
datetime,
|
|
15
|
-
)
|
|
13
|
+
from datetime import datetime, timezone
|
|
16
14
|
from pathlib import (
|
|
17
15
|
Path,
|
|
18
16
|
)
|
|
@@ -153,10 +151,12 @@ class App(BaseModel):
|
|
|
153
151
|
size_json_filename: t.Optional[str] = None,
|
|
154
152
|
**kwargs: t.Any,
|
|
155
153
|
) -> None:
|
|
156
|
-
kwargs.update(
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
154
|
+
kwargs.update(
|
|
155
|
+
{
|
|
156
|
+
'app_dir': app_dir,
|
|
157
|
+
'target': target,
|
|
158
|
+
}
|
|
159
|
+
)
|
|
160
160
|
super().__init__(**kwargs)
|
|
161
161
|
|
|
162
162
|
# These internal variables store the paths with environment variables and placeholders;
|
|
@@ -169,12 +169,14 @@ class App(BaseModel):
|
|
|
169
169
|
self._is_build_log_path_temp = not bool(build_log_filename)
|
|
170
170
|
|
|
171
171
|
# pass all parameters to initialize hook method
|
|
172
|
-
kwargs.update(
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
172
|
+
kwargs.update(
|
|
173
|
+
{
|
|
174
|
+
'work_dir': self._work_dir,
|
|
175
|
+
'build_dir': self._build_dir,
|
|
176
|
+
'build_log_filename': build_log_filename,
|
|
177
|
+
'size_json_filename': size_json_filename,
|
|
178
|
+
}
|
|
179
|
+
)
|
|
178
180
|
self._kwargs = kwargs
|
|
179
181
|
self._initialize_hook(**kwargs)
|
|
180
182
|
|
|
@@ -472,11 +474,11 @@ class App(BaseModel):
|
|
|
472
474
|
def record_build_duration(func):
|
|
473
475
|
@functools.wraps(func)
|
|
474
476
|
def wrapper(self, *args, **kwargs):
|
|
475
|
-
self._build_timestamp = datetime.
|
|
477
|
+
self._build_timestamp = datetime.now(timezone.utc)
|
|
476
478
|
try:
|
|
477
479
|
return func(self, *args, **kwargs)
|
|
478
480
|
finally:
|
|
479
|
-
self._build_duration = (datetime.
|
|
481
|
+
self._build_duration = (datetime.now(timezone.utc) - self._build_timestamp).total_seconds()
|
|
480
482
|
|
|
481
483
|
return wrapper
|
|
482
484
|
|
|
@@ -544,6 +546,14 @@ class App(BaseModel):
|
|
|
544
546
|
modified_files: t.Union[t.List[str], str, None] = None,
|
|
545
547
|
check_app_dependencies: bool = False,
|
|
546
548
|
) -> None:
|
|
549
|
+
if self.build_status not in (
|
|
550
|
+
BuildStatus.UNKNOWN,
|
|
551
|
+
BuildStatus.SHOULD_BE_BUILT,
|
|
552
|
+
):
|
|
553
|
+
self.build_comment = f'Build {self.build_status.value}. Skipping...'
|
|
554
|
+
return
|
|
555
|
+
|
|
556
|
+
# real build starts here
|
|
547
557
|
self._pre_build()
|
|
548
558
|
|
|
549
559
|
try:
|
|
@@ -560,8 +570,16 @@ class App(BaseModel):
|
|
|
560
570
|
self._post_build()
|
|
561
571
|
|
|
562
572
|
def _post_build(self) -> None:
|
|
573
|
+
"""Post build actions for failed/success builds"""
|
|
574
|
+
if self.build_status not in (
|
|
575
|
+
BuildStatus.FAILED,
|
|
576
|
+
BuildStatus.SUCCESS,
|
|
577
|
+
):
|
|
578
|
+
return
|
|
579
|
+
|
|
563
580
|
self._build_stage = BuildStage.POST_BUILD
|
|
564
581
|
|
|
582
|
+
# both status applied
|
|
565
583
|
if self.copy_sdkconfig:
|
|
566
584
|
try:
|
|
567
585
|
shutil.copy(
|
|
@@ -573,12 +591,21 @@ class App(BaseModel):
|
|
|
573
591
|
else:
|
|
574
592
|
self._logger.debug('Copied sdkconfig file from %s to %s', self.work_dir, self.build_path)
|
|
575
593
|
|
|
594
|
+
# for originally success builds generate size.json if enabled
|
|
595
|
+
#
|
|
596
|
+
# for the rest of the actions, we need to check if there's further build warnings
|
|
597
|
+
# to tell if this build is successful or not
|
|
598
|
+
if self.build_status == BuildStatus.SUCCESS:
|
|
599
|
+
self.write_size_json()
|
|
600
|
+
|
|
576
601
|
if not os.path.isfile(self.build_log_path):
|
|
602
|
+
self._logger.warning(f'{self.build_log_path} does not exist. Skipping post build actions...')
|
|
577
603
|
return
|
|
578
604
|
|
|
605
|
+
# check warnings
|
|
579
606
|
has_unignored_warning = False
|
|
580
607
|
with open(self.build_log_path) as fr:
|
|
581
|
-
lines = [line.rstrip() for line in fr
|
|
608
|
+
lines = [line.rstrip() for line in fr if line.rstrip()]
|
|
582
609
|
for line in lines:
|
|
583
610
|
is_error_or_warning, ignored = self.is_error_or_warning(line)
|
|
584
611
|
if is_error_or_warning:
|
|
@@ -588,6 +615,14 @@ class App(BaseModel):
|
|
|
588
615
|
self._logger.warning('%s', line)
|
|
589
616
|
has_unignored_warning = True
|
|
590
617
|
|
|
618
|
+
# correct build status for originally successful builds
|
|
619
|
+
if self.build_status == BuildStatus.SUCCESS:
|
|
620
|
+
if self.check_warnings and has_unignored_warning:
|
|
621
|
+
self.build_status = BuildStatus.FAILED
|
|
622
|
+
self.build_comment = 'build succeeded with warnings'
|
|
623
|
+
elif has_unignored_warning:
|
|
624
|
+
self.build_comment = 'build succeeded with warnings'
|
|
625
|
+
|
|
591
626
|
if self.build_status == BuildStatus.FAILED:
|
|
592
627
|
# print last few lines to help debug
|
|
593
628
|
self._logger.error(
|
|
@@ -598,14 +633,14 @@ class App(BaseModel):
|
|
|
598
633
|
for line in lines[-self.LOG_DEBUG_LINES :]:
|
|
599
634
|
self._logger.error('%s', line)
|
|
600
635
|
|
|
601
|
-
|
|
636
|
+
return
|
|
637
|
+
|
|
638
|
+
# Actions for real success builds
|
|
639
|
+
# remove temp log file
|
|
640
|
+
if self._is_build_log_path_temp:
|
|
602
641
|
os.unlink(self.build_log_path)
|
|
603
642
|
self._logger.debug('Removed success build temporary log file: %s', self.build_log_path)
|
|
604
643
|
|
|
605
|
-
# Generate Size Files
|
|
606
|
-
if self.build_status == BuildStatus.SUCCESS:
|
|
607
|
-
self.write_size_json()
|
|
608
|
-
|
|
609
644
|
# Cleanup build directory if not preserving
|
|
610
645
|
if not self.preserve:
|
|
611
646
|
exclude_list = []
|
|
@@ -619,13 +654,6 @@ class App(BaseModel):
|
|
|
619
654
|
)
|
|
620
655
|
self._logger.debug('Removed built binaries under: %s', self.build_path)
|
|
621
656
|
|
|
622
|
-
# Build Result
|
|
623
|
-
if self.check_warnings and has_unignored_warning:
|
|
624
|
-
self.build_status = BuildStatus.FAILED
|
|
625
|
-
self.build_comment = 'build succeeded with warnings'
|
|
626
|
-
elif has_unignored_warning:
|
|
627
|
-
self.build_comment = 'build succeeded with warnings'
|
|
628
|
-
|
|
629
657
|
def _build(
|
|
630
658
|
self,
|
|
631
659
|
*,
|
|
@@ -665,12 +693,14 @@ class App(BaseModel):
|
|
|
665
693
|
else:
|
|
666
694
|
with open(self.size_json_path, 'w') as fw:
|
|
667
695
|
subprocess_run(
|
|
668
|
-
(
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
696
|
+
(
|
|
697
|
+
[
|
|
698
|
+
sys.executable,
|
|
699
|
+
str(IDF_SIZE_PY),
|
|
700
|
+
'--json',
|
|
701
|
+
map_file,
|
|
702
|
+
]
|
|
703
|
+
),
|
|
674
704
|
log_terminal=False,
|
|
675
705
|
log_fs=fw,
|
|
676
706
|
check=True,
|
|
@@ -922,7 +952,7 @@ class CMakeApp(App):
|
|
|
922
952
|
'-DSDKCONFIG_DEFAULTS={}'.format(';'.join(self.sdkconfig_files) if self.sdkconfig_files else ';'),
|
|
923
953
|
]
|
|
924
954
|
|
|
925
|
-
if modified_components is not None and check_app_dependencies
|
|
955
|
+
if self.build_status == BuildStatus.UNKNOWN and modified_components is not None and check_app_dependencies:
|
|
926
956
|
subprocess_run(
|
|
927
957
|
[*common_args, 'reconfigure'],
|
|
928
958
|
log_terminal=self._is_build_log_path_temp,
|
idf_build_apps/constants.py
CHANGED
|
@@ -80,6 +80,7 @@ IDF_VERSION = to_version(f'{IDF_VERSION_MAJOR}.{IDF_VERSION_MINOR}.{IDF_VERSION_
|
|
|
80
80
|
|
|
81
81
|
class BuildStatus(str, enum.Enum):
|
|
82
82
|
UNKNOWN = 'unknown'
|
|
83
|
+
DISABLED = 'disabled'
|
|
83
84
|
SKIPPED = 'skipped'
|
|
84
85
|
SHOULD_BE_BUILT = 'should be built'
|
|
85
86
|
FAILED = 'build failed'
|
|
@@ -98,14 +99,14 @@ class BuildStage(str, enum.Enum):
|
|
|
98
99
|
|
|
99
100
|
|
|
100
101
|
completion_instructions = """
|
|
101
|
-
With `--activate` option detect your shell type and add the appropriate commands to your shell's config file
|
|
102
|
-
so that it
|
|
102
|
+
With the `--activate` option, detect your shell type and add the appropriate commands to your shell's config file
|
|
103
|
+
so that it runs on startup. You will likely have to restart.
|
|
103
104
|
or re-login for the autocompletion to start working.
|
|
104
105
|
|
|
105
|
-
You can also specify your shell
|
|
106
|
+
You can also specify your shell using the `--shell` option.
|
|
106
107
|
|
|
107
|
-
If you do not want
|
|
108
|
-
|
|
108
|
+
If you do not want automatic modification of your shell configuration file
|
|
109
|
+
You can manually add the commands provided below to activate autocompletion.
|
|
109
110
|
or run them in your current terminal session for one-time activation.
|
|
110
111
|
|
|
111
112
|
Once again, you will likely have to restart
|
idf_build_apps/finder.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# SPDX-FileCopyrightText: 2022-
|
|
1
|
+
# SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
|
2
2
|
# SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
4
|
import logging
|
|
@@ -43,6 +43,7 @@ def _get_apps_from_path(
|
|
|
43
43
|
check_app_dependencies: bool = False,
|
|
44
44
|
sdkconfig_defaults_str: t.Optional[str] = None,
|
|
45
45
|
include_skipped_apps: bool = False,
|
|
46
|
+
include_disabled_apps: bool = False,
|
|
46
47
|
) -> t.List[App]:
|
|
47
48
|
modified_components = to_list(modified_components)
|
|
48
49
|
modified_files = to_list(modified_files)
|
|
@@ -50,7 +51,8 @@ def _get_apps_from_path(
|
|
|
50
51
|
def _validate_app(_app: App) -> bool:
|
|
51
52
|
if target not in _app.supported_targets:
|
|
52
53
|
LOGGER.debug('=> Ignored. %s only supports targets: %s', _app, ', '.join(_app.supported_targets))
|
|
53
|
-
|
|
54
|
+
_app.build_status = BuildStatus.DISABLED
|
|
55
|
+
return include_disabled_apps
|
|
54
56
|
|
|
55
57
|
_app._check_should_build(
|
|
56
58
|
manifest_rootpath=manifest_rootpath,
|
idf_build_apps/junit/report.py
CHANGED
|
@@ -38,6 +38,7 @@ import os.path
|
|
|
38
38
|
import typing as t
|
|
39
39
|
from datetime import (
|
|
40
40
|
datetime,
|
|
41
|
+
timezone,
|
|
41
42
|
)
|
|
42
43
|
from xml.etree import (
|
|
43
44
|
ElementTree,
|
|
@@ -81,14 +82,17 @@ class TestCase:
|
|
|
81
82
|
raise ValueError('Only one of failure_reason, skipped_reason, error_reason can be set')
|
|
82
83
|
|
|
83
84
|
self.duration_sec = duration_sec
|
|
84
|
-
self.timestamp = timestamp or datetime.
|
|
85
|
+
self.timestamp = timestamp or datetime.now(timezone.utc)
|
|
85
86
|
|
|
86
87
|
self.properties = properties or {}
|
|
87
88
|
|
|
88
89
|
@classmethod
|
|
89
90
|
def from_app(cls, app: App) -> 'TestCase':
|
|
90
|
-
if app.build_status
|
|
91
|
-
raise ValueError(
|
|
91
|
+
if app.build_status in (BuildStatus.UNKNOWN, BuildStatus.SHOULD_BE_BUILT):
|
|
92
|
+
raise ValueError(
|
|
93
|
+
f'Cannot create build report for apps with build status {app.build_status}. '
|
|
94
|
+
f'Please finish the build process first.'
|
|
95
|
+
)
|
|
92
96
|
|
|
93
97
|
kwargs: t.Dict[str, t.Any] = {
|
|
94
98
|
'name': app.build_path,
|
|
@@ -98,7 +102,7 @@ class TestCase:
|
|
|
98
102
|
}
|
|
99
103
|
if app.build_status == BuildStatus.FAILED:
|
|
100
104
|
kwargs['failure_reason'] = app.build_comment
|
|
101
|
-
elif app.build_status
|
|
105
|
+
elif app.build_status in (BuildStatus.DISABLED, BuildStatus.SKIPPED):
|
|
102
106
|
kwargs['skipped_reason'] = app.build_comment
|
|
103
107
|
|
|
104
108
|
if app.size_json_path and os.path.isfile(app.size_json_path):
|
|
@@ -106,7 +110,7 @@ class TestCase:
|
|
|
106
110
|
for k, v in json.load(f).items():
|
|
107
111
|
kwargs['properties'][f'{k}'] = str(v)
|
|
108
112
|
|
|
109
|
-
return cls(**kwargs)
|
|
113
|
+
return cls(**kwargs)
|
|
110
114
|
|
|
111
115
|
@property
|
|
112
116
|
def is_failed(self) -> bool:
|
|
@@ -155,7 +159,7 @@ class TestSuite:
|
|
|
155
159
|
self.skipped = 0
|
|
156
160
|
|
|
157
161
|
self.duration_sec: float = 0
|
|
158
|
-
self.timestamp = datetime.
|
|
162
|
+
self.timestamp = datetime.now(timezone.utc)
|
|
159
163
|
|
|
160
164
|
self.properties = get_sys_info()
|
|
161
165
|
|
idf_build_apps/junit/utils.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
|
1
|
+
# SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
|
2
2
|
# SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
4
|
import os
|
|
@@ -26,7 +26,7 @@ def get_processor_name():
|
|
|
26
26
|
if os.path.isfile('/proc/cpuinfo'):
|
|
27
27
|
try:
|
|
28
28
|
with open('/proc/cpuinfo') as f:
|
|
29
|
-
for line in f
|
|
29
|
+
for line in f:
|
|
30
30
|
if 'model name' in line:
|
|
31
31
|
return re.sub('.*model name.*:', '', line, 1).strip()
|
|
32
32
|
except Exception:
|
idf_build_apps/main.py
CHANGED
|
@@ -11,6 +11,7 @@ import re
|
|
|
11
11
|
import sys
|
|
12
12
|
import textwrap
|
|
13
13
|
import typing as t
|
|
14
|
+
from copy import deepcopy
|
|
14
15
|
|
|
15
16
|
import argcomplete
|
|
16
17
|
from pydantic import (
|
|
@@ -127,6 +128,7 @@ def find_apps(
|
|
|
127
128
|
ignore_app_dependencies_filepatterns: t.Optional[t.Union[t.List[str], str]] = None,
|
|
128
129
|
sdkconfig_defaults: t.Optional[str] = None,
|
|
129
130
|
include_skipped_apps: bool = False,
|
|
131
|
+
include_disabled_apps: bool = False,
|
|
130
132
|
) -> t.List[App]:
|
|
131
133
|
"""
|
|
132
134
|
Find app directories in paths (possibly recursively), which contain apps for the given build system, compatible
|
|
@@ -158,6 +160,7 @@ def find_apps(
|
|
|
158
160
|
:param sdkconfig_defaults: semicolon-separated string, pass to idf.py -DSDKCONFIG_DEFAULTS if specified,
|
|
159
161
|
also could be set via environment variables "SDKCONFIG_DEFAULTS"
|
|
160
162
|
:param include_skipped_apps: include skipped apps or not
|
|
163
|
+
:param include_disabled_apps: include disabled apps or not
|
|
161
164
|
:return: list of found apps
|
|
162
165
|
"""
|
|
163
166
|
if default_build_targets:
|
|
@@ -223,6 +226,7 @@ def find_apps(
|
|
|
223
226
|
modified_files=modified_files,
|
|
224
227
|
sdkconfig_defaults_str=sdkconfig_defaults,
|
|
225
228
|
include_skipped_apps=include_skipped_apps,
|
|
229
|
+
include_disabled_apps=include_disabled_apps,
|
|
226
230
|
)
|
|
227
231
|
)
|
|
228
232
|
|
|
@@ -365,12 +369,14 @@ def build_apps(
|
|
|
365
369
|
if os.path.isfile(app.size_json_path):
|
|
366
370
|
with open(build_apps_args.collect_size_info, 'a') as fw:
|
|
367
371
|
fw.write(
|
|
368
|
-
json.dumps(
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
372
|
+
json.dumps(
|
|
373
|
+
{
|
|
374
|
+
'app_name': app.name,
|
|
375
|
+
'config_name': app.config_name,
|
|
376
|
+
'target': app.target,
|
|
377
|
+
'path': app.size_json_path,
|
|
378
|
+
}
|
|
379
|
+
)
|
|
374
380
|
+ '\n'
|
|
375
381
|
)
|
|
376
382
|
LOGGER.debug('Recorded size info file path in %s', build_apps_args.collect_size_info)
|
|
@@ -551,14 +557,19 @@ def get_parser() -> argparse.ArgumentParser:
|
|
|
551
557
|
action='store_true',
|
|
552
558
|
help='Exit with error if any of the manifest rules does not exist on your filesystem',
|
|
553
559
|
)
|
|
554
|
-
|
|
560
|
+
common_args.add_argument(
|
|
561
|
+
'--enable-preview-targets',
|
|
562
|
+
action='store_true',
|
|
563
|
+
help='Build the apps with all targets in the current ESP-IDF branch, '
|
|
564
|
+
'including preview targets, when the app supports the target.',
|
|
565
|
+
)
|
|
555
566
|
common_args.add_argument(
|
|
556
567
|
'--default-build-targets',
|
|
557
568
|
nargs='+',
|
|
558
|
-
help='space-separated list of
|
|
559
|
-
'
|
|
569
|
+
help='space-separated list of string which specifies the targets for building the apps. '
|
|
570
|
+
'If provided, the apps will be built only with the specified targets '
|
|
571
|
+
'when the app supports the target.',
|
|
560
572
|
)
|
|
561
|
-
|
|
562
573
|
common_args.add_argument(
|
|
563
574
|
'--modified-components',
|
|
564
575
|
type=semicolon_separated_str_to_list,
|
|
@@ -610,7 +621,7 @@ def get_parser() -> argparse.ArgumentParser:
|
|
|
610
621
|
|
|
611
622
|
find_parser = actions.add_parser(
|
|
612
623
|
'find',
|
|
613
|
-
help='Find the buildable applications. Run `idf-build-apps find --help` for more information on a command',
|
|
624
|
+
help='Find the buildable applications. Run `idf-build-apps find --help` for more information on a command.',
|
|
614
625
|
description='Find the buildable applications in the given path or paths for specified chips. '
|
|
615
626
|
'`--path` and `--target` options must be provided. '
|
|
616
627
|
'By default, print the found apps in stdout. '
|
|
@@ -618,12 +629,23 @@ def get_parser() -> argparse.ArgumentParser:
|
|
|
618
629
|
parents=[common_args],
|
|
619
630
|
formatter_class=IdfBuildAppsCliFormatter,
|
|
620
631
|
)
|
|
621
|
-
|
|
622
632
|
find_parser.add_argument('-o', '--output', help='Print the found apps to the specified file instead of stdout')
|
|
633
|
+
find_parser.add_argument(
|
|
634
|
+
'--output-format',
|
|
635
|
+
choices=['raw', 'json'],
|
|
636
|
+
default='raw',
|
|
637
|
+
help='Output format. In "raw" format, each line is a valid json that represents the app. '
|
|
638
|
+
'In "json" format, the whole file is a JSON file of a list of apps.',
|
|
639
|
+
)
|
|
640
|
+
find_parser.add_argument(
|
|
641
|
+
'--include-all-apps',
|
|
642
|
+
action='store_true',
|
|
643
|
+
help='Include skipped and disabled apps. By default only apps that should be built.',
|
|
644
|
+
)
|
|
623
645
|
|
|
624
646
|
build_parser = actions.add_parser(
|
|
625
647
|
'build',
|
|
626
|
-
help='Build the found applications. Run `idf-build-apps build --help` for more information on a command',
|
|
648
|
+
help='Build the found applications. Run `idf-build-apps build --help` for more information on a command.',
|
|
627
649
|
description='Build the application in the given path or paths for specified chips. '
|
|
628
650
|
'`--path` and `--target` options must be provided.',
|
|
629
651
|
parents=[common_args],
|
|
@@ -696,18 +718,18 @@ def get_parser() -> argparse.ArgumentParser:
|
|
|
696
718
|
completions_parser = actions.add_parser(
|
|
697
719
|
'completions',
|
|
698
720
|
help='Add the autocompletion activation script to the shell rc file. '
|
|
699
|
-
'Run `idf-build-apps
|
|
721
|
+
'Run `idf-build-apps completions --help` for more information on a command.',
|
|
700
722
|
description='Without `--activate` option print instructions for manual activation. '
|
|
701
|
-
'With `--activate` option add the autocompletion activation script to the shell rc file '
|
|
702
|
-
'for bash, zsh, or fish. Other shells are not supported.
|
|
703
|
-
'The `--shell` option used only with the `--activate` option, '
|
|
723
|
+
'With the `--activate` option, add the autocompletion activation script to the shell rc file '
|
|
724
|
+
'for bash, zsh, or fish. Other shells are not supported.'
|
|
725
|
+
'The `--shell` option is used only with the `--activate` option, '
|
|
704
726
|
'if provided, add the autocompletion activation script to the given shell; '
|
|
705
727
|
'without this argument, will detect shell type automatically. '
|
|
706
728
|
'May need to restart or re-login for the autocompletion to start working',
|
|
707
729
|
formatter_class=IdfBuildAppsCliFormatter,
|
|
708
730
|
)
|
|
709
731
|
completions_parser.add_argument(
|
|
710
|
-
'-a', '--activate', action='store_true', help='Activate autocompletion automatically and permanently'
|
|
732
|
+
'-a', '--activate', action='store_true', help='Activate autocompletion automatically and permanently. '
|
|
711
733
|
)
|
|
712
734
|
completions_parser.add_argument(
|
|
713
735
|
'-s',
|
|
@@ -751,14 +773,15 @@ def validate_args(parser: argparse.ArgumentParser, args: argparse.Namespace) ->
|
|
|
751
773
|
if args.default_build_targets:
|
|
752
774
|
for target in args.default_build_targets:
|
|
753
775
|
if target not in ALL_TARGETS:
|
|
754
|
-
|
|
755
|
-
f'Unrecognizable target {target} specified with "--default-build-targets". '
|
|
776
|
+
LOGGER.warning(
|
|
777
|
+
f'Ignoring... Unrecognizable target {target} specified with "--default-build-targets". '
|
|
756
778
|
f'Current ESP-IDF available targets: {ALL_TARGETS}'
|
|
757
779
|
)
|
|
758
|
-
|
|
759
|
-
if target not in default_build_targets:
|
|
780
|
+
elif target not in default_build_targets:
|
|
760
781
|
default_build_targets.append(target)
|
|
761
|
-
|
|
782
|
+
args.default_build_targets = default_build_targets
|
|
783
|
+
elif args.enable_preview_targets:
|
|
784
|
+
args.default_build_targets = deepcopy(ALL_TARGETS)
|
|
762
785
|
|
|
763
786
|
if args.ignore_app_dependencies_components is not None:
|
|
764
787
|
if args.modified_components is None:
|
|
@@ -796,36 +819,49 @@ def main():
|
|
|
796
819
|
if args.action == 'build':
|
|
797
820
|
args.output = None # build action doesn't support output option
|
|
798
821
|
|
|
822
|
+
kwargs = {
|
|
823
|
+
'build_system': args.build_system,
|
|
824
|
+
'recursive': args.recursive,
|
|
825
|
+
'exclude_list': args.exclude or [],
|
|
826
|
+
'work_dir': args.work_dir,
|
|
827
|
+
'build_dir': args.build_dir or 'build',
|
|
828
|
+
'config_rules_str': args.config,
|
|
829
|
+
'build_log_filename': args.build_log,
|
|
830
|
+
'size_json_filename': args.size_file,
|
|
831
|
+
'check_warnings': args.check_warnings,
|
|
832
|
+
'manifest_rootpath': args.manifest_rootpath,
|
|
833
|
+
'manifest_files': args.manifest_file,
|
|
834
|
+
'check_manifest_rules': args.check_manifest_rules,
|
|
835
|
+
'default_build_targets': args.default_build_targets,
|
|
836
|
+
'modified_components': args.modified_components,
|
|
837
|
+
'modified_files': args.modified_files,
|
|
838
|
+
'ignore_app_dependencies_components': args.ignore_app_dependencies_components,
|
|
839
|
+
'ignore_app_dependencies_filepatterns': args.ignore_app_dependencies_filepatterns,
|
|
840
|
+
'sdkconfig_defaults': args.sdkconfig_defaults,
|
|
841
|
+
}
|
|
842
|
+
# only useful in find
|
|
843
|
+
if args.action == 'find' and args.include_all_apps:
|
|
844
|
+
kwargs['include_skipped_apps'] = True
|
|
845
|
+
kwargs['include_disabled_apps'] = True
|
|
846
|
+
|
|
799
847
|
# real call starts here
|
|
800
|
-
apps = find_apps(
|
|
801
|
-
args.paths,
|
|
802
|
-
args.target,
|
|
803
|
-
build_system=args.build_system,
|
|
804
|
-
recursive=args.recursive,
|
|
805
|
-
exclude_list=args.exclude or [],
|
|
806
|
-
work_dir=args.work_dir,
|
|
807
|
-
build_dir=args.build_dir or 'build',
|
|
808
|
-
config_rules_str=args.config,
|
|
809
|
-
build_log_filename=args.build_log,
|
|
810
|
-
size_json_filename=args.size_file,
|
|
811
|
-
check_warnings=args.check_warnings,
|
|
812
|
-
manifest_rootpath=args.manifest_rootpath,
|
|
813
|
-
manifest_files=args.manifest_file,
|
|
814
|
-
check_manifest_rules=args.check_manifest_rules,
|
|
815
|
-
default_build_targets=args.default_build_targets,
|
|
816
|
-
modified_components=args.modified_components,
|
|
817
|
-
modified_files=args.modified_files,
|
|
818
|
-
ignore_app_dependencies_components=args.ignore_app_dependencies_components,
|
|
819
|
-
ignore_app_dependencies_filepatterns=args.ignore_app_dependencies_filepatterns,
|
|
820
|
-
sdkconfig_defaults=args.sdkconfig_defaults,
|
|
821
|
-
)
|
|
848
|
+
apps = find_apps(args.paths, args.target, **kwargs)
|
|
822
849
|
|
|
823
850
|
if args.action == 'find':
|
|
824
851
|
if args.output:
|
|
825
852
|
os.makedirs(os.path.dirname(os.path.realpath(args.output)), exist_ok=True)
|
|
853
|
+
if args.output.endswith('.json'):
|
|
854
|
+
LOGGER.info('Detecting output file ends with ".json", writing json file.')
|
|
855
|
+
args.output_format = 'json'
|
|
856
|
+
|
|
826
857
|
with open(args.output, 'w') as fw:
|
|
827
|
-
|
|
828
|
-
|
|
858
|
+
if args.output_format == 'raw':
|
|
859
|
+
for app in apps:
|
|
860
|
+
fw.write(app.to_json() + '\n')
|
|
861
|
+
elif args.output_format == 'json':
|
|
862
|
+
fw.write(json.dumps([app.model_dump() for app in apps], indent=2))
|
|
863
|
+
else:
|
|
864
|
+
raise ValueError(f'Output format {args.output_format} is not supported.')
|
|
829
865
|
else:
|
|
830
866
|
for app in apps:
|
|
831
867
|
print(app)
|
|
@@ -94,20 +94,24 @@ class SocHeader(dict):
|
|
|
94
94
|
|
|
95
95
|
@classmethod
|
|
96
96
|
def _parse_soc_header(cls, target: str) -> t.Dict[str, t.Any]:
|
|
97
|
-
soc_headers_dirs = cls._get_dirs_from_candidates(
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
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
|
+
)
|
|
111
115
|
|
|
112
116
|
header_files: t.List[str] = []
|
|
113
117
|
for d in [*soc_headers_dirs, *esp_rom_headers_dirs]:
|
|
@@ -1,26 +1,26 @@
|
|
|
1
|
-
idf_build_apps/__init__.py,sha256=
|
|
1
|
+
idf_build_apps/__init__.py,sha256=BwKVA9OBak7HwLAOrcfYb-ir3L5sCQDsB_FC7GO4KjE,650
|
|
2
2
|
idf_build_apps/__main__.py,sha256=8E-5xHm2MlRun0L88XJleNh5U50dpE0Q1nK5KqomA7I,182
|
|
3
|
-
idf_build_apps/app.py,sha256=
|
|
3
|
+
idf_build_apps/app.py,sha256=q9udvZyBG3qWrNxlyuG3iTiLcayOSrSwRuyL2n7QALY,37002
|
|
4
4
|
idf_build_apps/autocompletions.py,sha256=g-bx0pzXoFKI0VQqftkHyGVWN6MLjuFOdozeuAf45yo,2138
|
|
5
5
|
idf_build_apps/build_apps_args.py,sha256=r6VCJDdCzE873X8OTputYkCBZPgECaKoNlAejfcamJk,1644
|
|
6
6
|
idf_build_apps/config.py,sha256=I75uOQGarCWVKGi16ZYpo0qTVU25BUP4eh6-RWCtbvw,2924
|
|
7
|
-
idf_build_apps/constants.py,sha256=
|
|
8
|
-
idf_build_apps/finder.py,sha256=
|
|
7
|
+
idf_build_apps/constants.py,sha256=8Bh99xGFpyLkEovQMglS2KydxoEZesAHQSgdpsUnSTM,4000
|
|
8
|
+
idf_build_apps/finder.py,sha256=2TOQ6fq9q3MtsLnG4o0VvA2aMd3Zb6w6CL-U_tQrT3k,6362
|
|
9
9
|
idf_build_apps/log.py,sha256=JysogBHoompfW9E9w0U4wZH7tt8dBdfoh-stPXQz1hw,2573
|
|
10
|
-
idf_build_apps/main.py,sha256=
|
|
10
|
+
idf_build_apps/main.py,sha256=wKDt5iQKjpDmxJecPJMMMYb2kDI2qIRH_Qlkg3u6jlY,39199
|
|
11
11
|
idf_build_apps/session_args.py,sha256=2WDTy40IFAc0KQ57HaeBcYj_k10eUXRKkDOWLrFCaHY,2985
|
|
12
12
|
idf_build_apps/utils.py,sha256=dYxNXPe7FRWxzUFlTzOb3G-LpKpRUrNWdQrsO5MXAB8,9702
|
|
13
13
|
idf_build_apps/junit/__init__.py,sha256=IxvdaS6eSXp7kZxRuXqyZyGxuA_A1nOW1jF1HMi8Gns,231
|
|
14
|
-
idf_build_apps/junit/report.py,sha256=
|
|
15
|
-
idf_build_apps/junit/utils.py,sha256=
|
|
14
|
+
idf_build_apps/junit/report.py,sha256=T7dVU3Sz5tqjfbcFW7wjsb65PDH6C2HFf73ePJqBhMs,6555
|
|
15
|
+
idf_build_apps/junit/utils.py,sha256=j0PYhFTZjXtTwkENdeL4bFJcX24ktf1CsOOVXz65yNo,1297
|
|
16
16
|
idf_build_apps/manifest/__init__.py,sha256=Q2-cb3ngNjnl6_zWhUfzZZB10f_-Rv2JYNck3Lk7UkQ,133
|
|
17
17
|
idf_build_apps/manifest/if_parser.py,sha256=r0pivV9gmniPn3Ia6sTMbW5tFAKInhOXk-Lfd6GokqE,6381
|
|
18
18
|
idf_build_apps/manifest/manifest.py,sha256=P5ZaUd72A_HOVF6iuwap__Bw-w7WI72ugiTURm9PNNQ,10708
|
|
19
|
-
idf_build_apps/manifest/soc_header.py,sha256=
|
|
19
|
+
idf_build_apps/manifest/soc_header.py,sha256=PzJ37xFspt5f0AXWvAFNA_avHZA9fMXHBrwDYLi3qEI,4344
|
|
20
20
|
idf_build_apps/yaml/__init__.py,sha256=W-3z5no07RQ6eYKGyOAPA8Z2CLiMPob8DD91I4URjrA,162
|
|
21
21
|
idf_build_apps/yaml/parser.py,sha256=Y2OyB4g1DCC7C7jrvpIyZV9lgeCB_XvuB75iGmqiTaM,2093
|
|
22
|
-
idf_build_apps-2.4.
|
|
23
|
-
idf_build_apps-2.4.
|
|
24
|
-
idf_build_apps-2.4.
|
|
25
|
-
idf_build_apps-2.4.
|
|
26
|
-
idf_build_apps-2.4.
|
|
22
|
+
idf_build_apps-2.4.2.dist-info/entry_points.txt,sha256=3pVUirUEsb6jsDRikkQWNUt4hqLK2ci1HvW_Vf8b6uE,59
|
|
23
|
+
idf_build_apps-2.4.2.dist-info/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
|
|
24
|
+
idf_build_apps-2.4.2.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81
|
|
25
|
+
idf_build_apps-2.4.2.dist-info/METADATA,sha256=wk_YDe56T2b3qXhknNIRzcBtCpvcDQCqku22o7IbYIU,4608
|
|
26
|
+
idf_build_apps-2.4.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|