Skip to content

Commit df5c0bc

Browse files
authored
Merge pull request #185 from espressif/feat/improve-debugging
feat: improve debug info
2 parents 4b86b67 + b6f3d78 commit df5c0bc

File tree

7 files changed

+141
-134
lines changed

7 files changed

+141
-134
lines changed

.pre-commit-config.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ repos:
3838
- pytest
3939
- argcomplete>=3
4040
- esp-bool-parser>=0.1.2,<1
41+
- rich
4142
- repo: https://github.com/hfudev/rstfmt
4243
rev: v0.1.4
4344
hooks:

idf_build_apps/app.py

Lines changed: 32 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@
3636
IDF_VERSION_PATCH,
3737
PREVIEW_TARGETS,
3838
PROJECT_DESCRIPTION_JSON,
39-
BuildStage,
4039
BuildStatus,
4140
)
4241
from .manifest.manifest import (
@@ -55,17 +54,7 @@
5554
to_list,
5655
)
5756

58-
59-
class _AppBuildStageFilter(logging.Filter):
60-
def __init__(self, *args, app, **kwargs):
61-
super().__init__(*args, **kwargs)
62-
self.app = app
63-
64-
def filter(self, record: logging.LogRecord) -> bool:
65-
if self.app._build_stage:
66-
record.build_stage = self.app._build_stage.value
67-
68-
return True
57+
LOGGER = logging.getLogger(__name__)
6958

7059

7160
class App(BaseModel):
@@ -120,7 +109,6 @@ class App(BaseModel):
120109
build_status: BuildStatus = BuildStatus.UNKNOWN
121110
build_comment: t.Optional[str] = None
122111

123-
_build_stage: t.Optional[BuildStage] = None
124112
_build_duration: float = 0
125113
_build_timestamp: t.Optional[datetime] = None
126114

@@ -176,9 +164,6 @@ def __init__(
176164
# private attrs, won't be dumped to json
177165
self._checked_should_build = False
178166

179-
self._logger = logging.getLogger(f'{__name__}.{hash(self)}')
180-
self._logger.addFilter(_AppBuildStageFilter(app=self))
181-
182167
self._sdkconfig_files, self._sdkconfig_files_defined_target = self._process_sdkconfig_files()
183168

184169
@classmethod
@@ -346,10 +331,10 @@ def _process_sdkconfig_files(self) -> t.Tuple[t.List[str], t.Optional[str]]:
346331
# use filepath if abs/rel already point to itself
347332
if not os.path.isfile(f):
348333
# find it in the app_dir
349-
self._logger.debug('sdkconfig file %s not found, checking under app_dir...', f)
334+
LOGGER.debug('sdkconfig file %s not found, checking under app_dir...', f)
350335
f = os.path.join(self.app_dir, f)
351336
if not os.path.isfile(f):
352-
self._logger.debug('sdkconfig file %s not found, skipping...', f)
337+
LOGGER.debug('sdkconfig file %s not found, skipping...', f)
353338
continue
354339

355340
expanded_fp = os.path.join(expanded_dir, os.path.basename(f))
@@ -377,22 +362,22 @@ def _process_sdkconfig_files(self) -> t.Tuple[t.List[str], t.Optional[str]]:
377362
with open(f) as fr:
378363
with open(expanded_fp) as new_fr:
379364
if fr.read() == new_fr.read():
380-
self._logger.debug('Use sdkconfig file %s', f)
365+
LOGGER.debug('Use sdkconfig file %s', f)
381366
try:
382367
os.unlink(expanded_fp)
383368
except OSError:
384-
self._logger.debug('Failed to remove file %s', expanded_fp)
369+
LOGGER.debug('Failed to remove file %s', expanded_fp)
385370
real_sdkconfig_files.append(f)
386371
else:
387-
self._logger.debug('Expand sdkconfig file %s to %s', f, expanded_fp)
372+
LOGGER.debug('Expand sdkconfig file %s to %s', f, expanded_fp)
388373
real_sdkconfig_files.append(expanded_fp)
389374
# copy the related target-specific sdkconfig files
390375
par_dir = os.path.abspath(os.path.join(f, '..'))
391376
for target_specific_file in (
392377
os.path.join(par_dir, str(p))
393378
for p in Path(par_dir).glob(os.path.basename(f) + f'.{self.target}')
394379
):
395-
self._logger.debug(
380+
LOGGER.debug(
396381
'Copy target-specific sdkconfig file %s to %s', target_specific_file, expanded_dir
397382
)
398383
shutil.copy(target_specific_file, expanded_dir)
@@ -474,21 +459,16 @@ def wrapper(self, *args, **kwargs):
474459
return wrapper
475460

476461
def _pre_build(self) -> None:
477-
if self.dry_run:
478-
self._build_stage = BuildStage.DRY_RUN
479-
else:
480-
self._build_stage = BuildStage.PRE_BUILD
481-
482462
if self.build_status == BuildStatus.SKIPPED:
483463
return
484464

485465
if self.work_dir != self.app_dir:
486466
if os.path.exists(self.work_dir):
487-
self._logger.debug('Removed existing work dir: %s', self.work_dir)
467+
LOGGER.debug('Removed existing work dir: %s', self.work_dir)
488468
if not self.dry_run:
489469
shutil.rmtree(self.work_dir)
490470

491-
self._logger.debug('Copied app from %s to %s', self.app_dir, self.work_dir)
471+
LOGGER.debug('Copied app from %s to %s', self.app_dir, self.work_dir)
492472
if not self.dry_run:
493473
# if the new directory inside the original directory,
494474
# make sure not to go into recursion.
@@ -502,7 +482,7 @@ def _pre_build(self) -> None:
502482
shutil.copytree(self.app_dir, self.work_dir, ignore=ignore, symlinks=True)
503483

504484
if os.path.exists(self.build_path):
505-
self._logger.debug('Removed existing build dir: %s', self.build_path)
485+
LOGGER.debug('Removed existing build dir: %s', self.build_path)
506486
if not self.dry_run:
507487
shutil.rmtree(self.build_path)
508488

@@ -511,17 +491,17 @@ def _pre_build(self) -> None:
511491

512492
sdkconfig_file = os.path.join(self.work_dir, 'sdkconfig')
513493
if os.path.exists(sdkconfig_file):
514-
self._logger.debug('Removed existing sdkconfig file: %s', sdkconfig_file)
494+
LOGGER.debug('Removed existing sdkconfig file: %s', sdkconfig_file)
515495
if not self.dry_run:
516496
os.unlink(sdkconfig_file)
517497

518498
if os.path.isfile(self.build_log_path):
519-
self._logger.debug('Removed existing build log file: %s', self.build_log_path)
499+
LOGGER.debug('Removed existing build log file: %s', self.build_log_path)
520500
if not self.dry_run:
521501
os.unlink(self.build_log_path)
522502
elif not self.dry_run:
523503
os.makedirs(os.path.dirname(self.build_log_path), exist_ok=True)
524-
self._logger.info('Writing build log to %s', self.build_log_path)
504+
LOGGER.info('Writing build log to %s', self.build_log_path)
525505

526506
if self.dry_run:
527507
self.build_status = BuildStatus.SKIPPED
@@ -570,8 +550,6 @@ def _post_build(self) -> None:
570550
):
571551
return
572552

573-
self._build_stage = BuildStage.POST_BUILD
574-
575553
# both status applied
576554
if self.copy_sdkconfig:
577555
try:
@@ -580,9 +558,9 @@ def _post_build(self) -> None:
580558
os.path.join(self.build_path, 'sdkconfig'),
581559
)
582560
except Exception as e:
583-
self._logger.warning('Copy sdkconfig file from failed: %s', e)
561+
LOGGER.warning('Copy sdkconfig file from failed: %s', e)
584562
else:
585-
self._logger.debug('Copied sdkconfig file from %s to %s', self.work_dir, self.build_path)
563+
LOGGER.debug('Copied sdkconfig file from %s to %s', self.work_dir, self.build_path)
586564

587565
# for originally success builds generate size.json if enabled
588566
#
@@ -592,7 +570,7 @@ def _post_build(self) -> None:
592570
self.write_size_json()
593571

594572
if not os.path.isfile(self.build_log_path):
595-
self._logger.warning(f'{self.build_log_path} does not exist. Skipping post build actions...')
573+
LOGGER.warning(f'{self.build_log_path} does not exist. Skipping post build actions...')
596574
return
597575

598576
# check warnings
@@ -603,21 +581,21 @@ def _post_build(self) -> None:
603581
is_error_or_warning, ignored = self.is_error_or_warning(line)
604582
if is_error_or_warning:
605583
if ignored:
606-
self._logger.info('[Ignored warning] %s', line)
584+
LOGGER.info('[Ignored warning] %s', line)
607585
else:
608-
self._logger.warning('%s', line)
586+
LOGGER.warning('%s', line)
609587
has_unignored_warning = True
610588

611589
# for failed builds, print last few lines to help debug
612590
if self.build_status == BuildStatus.FAILED:
613591
# print last few lines to help debug
614-
self._logger.error(
592+
LOGGER.error(
615593
'Last %s lines from the build log "%s":',
616594
self.LOG_DEBUG_LINES,
617595
self.build_log_path,
618596
)
619597
for line in lines[-self.LOG_DEBUG_LINES :]:
620-
self._logger.error('%s', line)
598+
LOGGER.error('%s', line)
621599
# correct build status for originally successful builds
622600
elif self.build_status == BuildStatus.SUCCESS:
623601
if self.check_warnings and has_unignored_warning:
@@ -636,7 +614,7 @@ def _finalize(self) -> None:
636614
# remove temp log file
637615
if self._is_build_log_path_temp:
638616
os.unlink(self.build_log_path)
639-
self._logger.debug('Removed success build temporary log file: %s', self.build_log_path)
617+
LOGGER.debug('Removed success build temporary log file: %s', self.build_log_path)
640618

641619
# Cleanup build directory if not preserving
642620
if not self.preserve:
@@ -649,25 +627,25 @@ def _finalize(self) -> None:
649627
self.build_path,
650628
exclude_file_patterns=exclude_list,
651629
)
652-
self._logger.debug('Removed built binaries under: %s', self.build_path)
630+
LOGGER.debug('Removed built binaries under: %s', self.build_path)
653631

654632
def _build(
655633
self,
656634
*,
657-
manifest_rootpath: t.Optional[str] = None, # noqa: ARG002
658-
modified_components: t.Optional[t.List[str]] = None, # noqa: ARG002
659-
modified_files: t.Optional[t.List[str]] = None, # noqa: ARG002
660-
check_app_dependencies: bool = False, # noqa: ARG002
635+
manifest_rootpath: t.Optional[str] = None,
636+
modified_components: t.Optional[t.List[str]] = None,
637+
modified_files: t.Optional[t.List[str]] = None,
638+
check_app_dependencies: bool = False,
661639
) -> None:
662-
self._build_stage = BuildStage.BUILD
640+
pass
663641

664642
def _write_size_json(self) -> None:
665643
if not self.size_json_path:
666644
return
667645

668646
map_file = find_first_match('*.map', self.build_path)
669647
if not map_file:
670-
self._logger.warning(
648+
LOGGER.warning(
671649
'.map file not found. Cannot write size json to file: %s',
672650
self.size_json_path,
673651
)
@@ -703,18 +681,18 @@ def _write_size_json(self) -> None:
703681
check=True,
704682
)
705683

706-
self._logger.debug('Generated size info to %s', self.size_json_path)
684+
LOGGER.debug('Generated size info to %s', self.size_json_path)
707685

708686
def write_size_json(self) -> None:
709687
if self.target in PREVIEW_TARGETS:
710688
# targets in preview may not yet have support in esp-idf-size
711-
self._logger.info('Skipping generation of size json for target %s as it is in preview.', self.target)
689+
LOGGER.info('Skipping generation of size json for target %s as it is in preview.', self.target)
712690
return
713691

714692
try:
715693
self._write_size_json()
716694
except Exception as e:
717-
self._logger.warning('Failed to generate size json: %s', e)
695+
LOGGER.warning('Failed to generate size json: %s', e)
718696

719697
def to_json(self) -> str:
720698
return self.model_dump_json()
@@ -969,7 +947,7 @@ def _build(
969947
check=True,
970948
additional_env_dict=additional_env_dict,
971949
)
972-
self._logger.debug('generated project_description.json to check app dependencies')
950+
LOGGER.debug('generated project_description.json to check app dependencies')
973951

974952
with open(os.path.join(self.build_path, PROJECT_DESCRIPTION_JSON)) as fr:
975953
build_components = {item for item in json.load(fr)['build_components'] if item}

idf_build_apps/constants.py

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -31,17 +31,6 @@ class BuildStatus(str, enum.Enum):
3131
SUCCESS = 'build success'
3232

3333

34-
class BuildStage(str, enum.Enum):
35-
DRY_RUN = 'Dry Run'
36-
PRE_BUILD = 'Pre Build'
37-
BUILD = 'Build'
38-
POST_BUILD = 'Post Build'
39-
40-
@classmethod
41-
def max_length(cls) -> int:
42-
return max(len(v.value) for v in cls.__members__.values())
43-
44-
4534
completion_instructions = """
4635
With the `--activate` option, detect your shell type and add the appropriate commands to your shell's config file
4736
so that it runs on startup. You will likely have to restart.

idf_build_apps/junit/report.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
1+
# SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
22
# SPDX-License-Identifier: Apache-2.0
33

44
"""
@@ -211,4 +211,4 @@ def create_test_report(self) -> None:
211211
xml.append(test_suite.to_xml_elem())
212212

213213
ElementTree.ElementTree(xml).write(self.filepath, encoding='utf-8')
214-
LOGGER.info('Test report written to %s', self.filepath)
214+
LOGGER.info('Generated build junit report at: %s', self.filepath)

0 commit comments

Comments
 (0)