idf-build-apps 2.5.3__py3-none-any.whl → 2.6.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.
@@ -1,4 +1,4 @@
1
- # SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
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.5.3'
11
+ __version__ = '2.6.1'
12
12
 
13
13
  from .session_args import (
14
14
  SessionArgs,
idf_build_apps/args.py CHANGED
@@ -1,4 +1,4 @@
1
- # SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
1
+ # SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
2
2
  # SPDX-License-Identifier: Apache-2.0
3
3
 
4
4
  import argparse
@@ -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
@@ -114,11 +115,13 @@ def get_meta(f: FieldInfo) -> t.Optional[FieldMetadata]:
114
115
  class BaseArguments(BaseSettings):
115
116
  """Base settings class for all settings classes"""
116
117
 
118
+ CONFIG_FILE_PATH: t.ClassVar[t.Optional[Path]] = None
119
+
117
120
  model_config = SettingsConfigDict(
118
- toml_file='.idf_build_apps.toml',
121
+ # these below two are supported in pydantic 2.6
119
122
  pyproject_toml_table_header=('tool', 'idf-build-apps'),
120
123
  pyproject_toml_depth=sys.maxsize,
121
- extra='ignore',
124
+ extra='ignore', # we're supporting pydantic <2.6 as well, so we ignore extra fields
122
125
  )
123
126
 
124
127
  @classmethod
@@ -130,11 +133,15 @@ class BaseArguments(BaseSettings):
130
133
  dotenv_settings: PydanticBaseSettingsSource, # noqa: ARG003
131
134
  file_secret_settings: PydanticBaseSettingsSource, # noqa: ARG003
132
135
  ) -> t.Tuple[PydanticBaseSettingsSource, ...]:
133
- return (
134
- init_settings,
135
- TomlConfigSettingsSource(settings_cls),
136
- PyprojectTomlConfigSettingsSource(settings_cls),
137
- )
136
+ sources: t.Tuple[PydanticBaseSettingsSource, ...] = (init_settings,)
137
+ if cls.CONFIG_FILE_PATH is None:
138
+ sources += (TomlConfigSettingsSource(settings_cls, toml_file=Path(IDF_BUILD_APPS_TOML_FN)),)
139
+ sources += (PyprojectTomlConfigSettingsSource(settings_cls, toml_file=Path('pyproject.toml')),)
140
+ else:
141
+ sources += (TomlConfigSettingsSource(settings_cls, toml_file=Path(cls.CONFIG_FILE_PATH)),)
142
+ sources += (PyprojectTomlConfigSettingsSource(settings_cls, toml_file=Path(cls.CONFIG_FILE_PATH)),)
143
+
144
+ return sources
138
145
 
139
146
  @field_validator('*', mode='before')
140
147
  @classmethod
@@ -143,8 +150,15 @@ class BaseArguments(BaseSettings):
143
150
  f = cls.model_fields[info.field_name]
144
151
  meta = get_meta(f)
145
152
  if meta and meta.validate_method:
146
- if ValidateMethod.TO_LIST in meta.validate_method:
147
- return to_list(v)
153
+ for method in meta.validate_method:
154
+ if method == ValidateMethod.TO_LIST:
155
+ v = to_list(v)
156
+ elif method == ValidateMethod.EXPAND_VARS:
157
+ v = os.path.expandvars(v)
158
+ else:
159
+ raise NotImplementedError(f'Unknown validate method: {method}')
160
+
161
+ return v
148
162
 
149
163
  return v
150
164
 
@@ -156,19 +170,19 @@ class GlobalArguments(BaseArguments):
156
170
  action='count',
157
171
  ),
158
172
  description='Verbosity level. By default set to WARNING. Specify -v for INFO, -vv for DEBUG',
159
- default=0,
173
+ default=0, # type: ignore
160
174
  )
161
175
  log_file: t.Optional[str] = field(
162
176
  None,
163
177
  description='Path to the log file, if not specified logs will be printed to stderr',
164
- default=None,
178
+ default=None, # type: ignore
165
179
  )
166
180
  no_color: bool = field(
167
181
  FieldMetadata(
168
182
  action='store_true',
169
183
  ),
170
184
  description='Disable colored output',
171
- default=False,
185
+ default=False, # type: ignore
172
186
  )
173
187
 
174
188
  def model_post_init(self, __context: Any) -> None:
@@ -190,7 +204,7 @@ class DependencyDrivenBuildArguments(GlobalArguments):
190
204
  ),
191
205
  description='Path to the manifest files which contains the build test rules of the apps',
192
206
  validation_alias=AliasChoices('manifest_files', 'manifest_file'),
193
- default=None,
207
+ default=None, # type: ignore
194
208
  )
195
209
  manifest_filepatterns: t.Optional[t.List[str]] = field(
196
210
  FieldMetadata(
@@ -199,13 +213,15 @@ class DependencyDrivenBuildArguments(GlobalArguments):
199
213
  ),
200
214
  description='space-separated list of file patterns to search for the manifest files. '
201
215
  'The matched files will be loaded as the manifest files.',
202
- default=None,
216
+ default=None, # type: ignore
203
217
  )
204
218
  manifest_rootpath: str = field(
205
- None,
219
+ FieldMetadata(
220
+ validate_method=[ValidateMethod.EXPAND_VARS],
221
+ ),
206
222
  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,
223
+ 'By default set to the current directory. Support environment variables.',
224
+ default=os.curdir, # type: ignore
209
225
  )
210
226
  modified_components: t.Optional[t.List[str]] = field(
211
227
  FieldMetadata(
@@ -215,7 +231,7 @@ class DependencyDrivenBuildArguments(GlobalArguments):
215
231
  description='semicolon-separated list of modified components. '
216
232
  'If set to "", the value would be considered as None. '
217
233
  'If set to ";", the value would be considered as an empty list.',
218
- default=None,
234
+ default=None, # type: ignore
219
235
  )
220
236
  modified_files: t.Optional[t.List[str]] = field(
221
237
  FieldMetadata(
@@ -225,7 +241,7 @@ class DependencyDrivenBuildArguments(GlobalArguments):
225
241
  description='semicolon-separated list of modified files. '
226
242
  'If set to "", the value would be considered as None. '
227
243
  'If set to ";", the value would be considered as an empty list.',
228
- default=None,
244
+ default=None, # type: ignore
229
245
  )
230
246
  deactivate_dependency_driven_build_by_components: t.Optional[t.List[str]] = field(
231
247
  FieldMetadata(
@@ -247,7 +263,7 @@ class DependencyDrivenBuildArguments(GlobalArguments):
247
263
  validation_alias=AliasChoices(
248
264
  'deactivate_dependency_driven_build_by_components', 'ignore_app_dependencies_components'
249
265
  ),
250
- default=None,
266
+ default=None, # type: ignore
251
267
  )
252
268
  deactivate_dependency_driven_build_by_filepatterns: t.Optional[t.List[str]] = field(
253
269
  FieldMetadata(
@@ -269,21 +285,21 @@ class DependencyDrivenBuildArguments(GlobalArguments):
269
285
  validation_alias=AliasChoices(
270
286
  'deactivate_dependency_driven_build_by_filepatterns', 'ignore_app_dependencies_filepatterns'
271
287
  ),
272
- default=None,
288
+ default=None, # type: ignore
273
289
  )
274
290
  check_manifest_rules: bool = field(
275
291
  FieldMetadata(
276
292
  action='store_true',
277
293
  ),
278
294
  description='Check if all folders defined in the manifest files exist. Fail if not',
279
- default=False,
295
+ default=False, # type: ignore
280
296
  )
281
297
  compare_manifest_sha_filepath: t.Optional[str] = field(
282
298
  None,
283
299
  description='Path to the file containing the hash of the manifest rules. '
284
300
  'Compare the hash with the current manifest rules. '
285
301
  'All matched apps will be built if the corresponding manifest rule is modified',
286
- default=None,
302
+ default=None, # type: ignore
287
303
  )
288
304
 
289
305
  def model_post_init(self, __context: Any) -> None:
@@ -377,28 +393,28 @@ class FindBuildArguments(DependencyDrivenBuildArguments):
377
393
  nargs='*',
378
394
  ),
379
395
  description='Paths to the directories containing the apps. By default set to the current directory',
380
- default=os.curdir,
396
+ default=os.curdir, # type: ignore
381
397
  )
382
398
  target: str = field(
383
399
  FieldMetadata(
384
400
  shorthand='-t',
385
401
  ),
386
402
  description='Filter the apps by target. By default set to "all"',
387
- default='all',
403
+ default='all', # type: ignore
388
404
  )
389
405
  build_system: t.Union[str, t.Type[App]] = field(
390
406
  FieldMetadata(
391
407
  choices=['cmake', 'make'],
392
408
  ),
393
409
  description='Filter the apps by build system. By default set to "cmake"',
394
- default='cmake',
410
+ default='cmake', # type: ignore
395
411
  )
396
412
  recursive: bool = field(
397
413
  FieldMetadata(
398
414
  action='store_true',
399
415
  ),
400
416
  description='Search for apps recursively under the specified paths',
401
- default=False,
417
+ default=False, # type: ignore
402
418
  )
403
419
  exclude: t.Optional[t.List[str]] = field(
404
420
  FieldMetadata(
@@ -407,20 +423,20 @@ class FindBuildArguments(DependencyDrivenBuildArguments):
407
423
  ),
408
424
  description='Ignore the specified directories while searching recursively',
409
425
  validation_alias=AliasChoices('exclude', 'exclude_list'),
410
- default=None,
426
+ default=None, # type: ignore
411
427
  )
412
428
  work_dir: t.Optional[str] = field(
413
429
  None,
414
430
  description='Copy the app to this directory before building. '
415
431
  'By default set to the app directory. Can expand placeholders',
416
- default=None,
432
+ default=None, # type: ignore
417
433
  )
418
434
  build_dir: str = field(
419
435
  None,
420
436
  description='Build directory for the app. By default set to "build". '
421
437
  'When set to relative path, it will be treated as relative to the app directory. '
422
438
  'Can expand placeholders',
423
- default='build',
439
+ default='build', # type: ignore
424
440
  )
425
441
  build_log_filename: t.Optional[str] = field(
426
442
  FieldMetadata(
@@ -428,7 +444,7 @@ class FindBuildArguments(DependencyDrivenBuildArguments):
428
444
  ),
429
445
  description='Log filename under the build directory instead of stdout. Can expand placeholders',
430
446
  validation_alias=AliasChoices('build_log_filename', 'build_log'),
431
- default=None,
447
+ default=None, # type: ignore
432
448
  )
433
449
  size_json_filename: t.Optional[str] = field(
434
450
  FieldMetadata(
@@ -436,7 +452,7 @@ class FindBuildArguments(DependencyDrivenBuildArguments):
436
452
  ),
437
453
  description='`idf.py size` output file under the build directory when specified. ' 'Can expand placeholders',
438
454
  validation_alias=AliasChoices('size_json_filename', 'size_file'),
439
- default=None,
455
+ default=None, # type: ignore
440
456
  )
441
457
  config_rules: t.Optional[t.List[str]] = field(
442
458
  FieldMetadata(
@@ -454,31 +470,31 @@ class FindBuildArguments(DependencyDrivenBuildArguments):
454
470
  'FILEPATTERN is the filename of the sdkconfig file with a single wildcard character (*). '
455
471
  'The NAME is the value matched by the wildcard',
456
472
  validation_alias=AliasChoices('config_rules', 'config_rules_str', 'config'),
457
- default=None,
473
+ default=None, # type: ignore
458
474
  )
459
475
  override_sdkconfig_items: t.Optional[str] = field(
460
476
  None,
461
477
  description='A comma-separated list of key=value pairs to override the sdkconfig items',
462
- default=None,
478
+ default=None, # type: ignore
463
479
  )
464
480
  override_sdkconfig_files: t.Optional[str] = field(
465
481
  None,
466
482
  description='A comma-separated list of sdkconfig files to override the sdkconfig items. '
467
483
  'When set to relative path, it will be treated as relative to the current directory',
468
- default=None,
484
+ default=None, # type: ignore
469
485
  )
470
486
  sdkconfig_defaults: t.Optional[str] = field(
471
487
  None,
472
488
  description='A semicolon-separated list of sdkconfig files passed to `idf.py -DSDKCONFIG_DEFAULTS`. '
473
489
  'SDKCONFIG_DEFAULTS environment variable is used when not specified',
474
- default=os.getenv('SDKCONFIG_DEFAULTS', None),
490
+ default=os.getenv('SDKCONFIG_DEFAULTS', None), # type: ignore
475
491
  )
476
492
  check_warnings: bool = field(
477
493
  FieldMetadata(
478
494
  action='store_true',
479
495
  ),
480
496
  description='Check for warnings in the build output. Fail if any warnings are found',
481
- default=False,
497
+ default=False, # type: ignore
482
498
  )
483
499
  default_build_targets: t.Optional[t.List[str]] = field(
484
500
  FieldMetadata(
@@ -487,7 +503,7 @@ class FindBuildArguments(DependencyDrivenBuildArguments):
487
503
  ),
488
504
  description='space-separated list of the default enabled build targets for the apps. '
489
505
  'When not specified, the default value is the targets listed by `idf.py --list-targets`',
490
- default=None,
506
+ default=None, # type: ignore
491
507
  )
492
508
  enable_preview_targets: bool = field(
493
509
  FieldMetadata(
@@ -495,28 +511,28 @@ class FindBuildArguments(DependencyDrivenBuildArguments):
495
511
  ),
496
512
  description='When enabled, the default build targets will be set to all apps, '
497
513
  'including the preview targets. As the targets defined in `idf.py --list-targets --preview`',
498
- default=False,
514
+ default=False, # type: ignore
499
515
  )
500
516
  include_skipped_apps: bool = field(
501
517
  FieldMetadata(
502
518
  action='store_true',
503
519
  ),
504
520
  description='Include the skipped apps in the output, together with the enabled ones',
505
- default=False,
521
+ default=False, # type: ignore
506
522
  )
507
523
  include_disabled_apps: bool = field(
508
524
  FieldMetadata(
509
525
  action='store_true',
510
526
  ),
511
527
  description='Include the disabled apps in the output, together with the enabled ones',
512
- default=False,
528
+ default=False, # type: ignore
513
529
  )
514
530
  include_all_apps: bool = field(
515
531
  FieldMetadata(
516
532
  action='store_true',
517
533
  ),
518
534
  description='Include skipped, and disabled apps in the output, together with the enabled ones',
519
- default=False,
535
+ default=False, # type: ignore
520
536
  )
521
537
 
522
538
  def model_post_init(self, __context: Any) -> None:
@@ -557,7 +573,7 @@ class FindArguments(FindBuildArguments):
557
573
  shorthand='-o',
558
574
  ),
559
575
  description='Record the found apps to the specified file instead of stdout',
560
- default=None,
576
+ default=None, # type: ignore
561
577
  )
562
578
  output_format: str = field(
563
579
  FieldMetadata(
@@ -566,7 +582,7 @@ class FindArguments(FindBuildArguments):
566
582
  description='Output format of the found apps. '
567
583
  'In "raw" format, each line is a json string serialized from the app model. '
568
584
  'In "json" format, the output is a json list of the serialized app models',
569
- default='raw',
585
+ default='raw', # type: ignore
570
586
  )
571
587
 
572
588
  def model_post_init(self, __context: Any) -> None:
@@ -587,7 +603,7 @@ class BuildArguments(FindBuildArguments):
587
603
  action='store_true',
588
604
  ),
589
605
  description='Enable verbose output of the build system',
590
- default=False,
606
+ default=False, # type: ignore
591
607
  )
592
608
  parallel_count: int = field(
593
609
  FieldMetadata(
@@ -597,7 +613,7 @@ class BuildArguments(FindBuildArguments):
597
613
  'Specified together with --parallel-index. '
598
614
  'The given apps will be divided into parallel_count parts, '
599
615
  'and the current run will build the parallel_index-th part',
600
- default=1,
616
+ default=1, # type: ignore
601
617
  )
602
618
  parallel_index: int = field(
603
619
  FieldMetadata(
@@ -607,28 +623,28 @@ class BuildArguments(FindBuildArguments):
607
623
  'Specified together with --parallel-count. '
608
624
  'The given apps will be divided into parallel_count parts, '
609
625
  'and the current run will build the parallel_index-th part',
610
- default=1,
626
+ default=1, # type: ignore
611
627
  )
612
628
  dry_run: bool = field(
613
629
  FieldMetadata(
614
630
  action='store_true',
615
631
  ),
616
632
  description='Skip the actual build, only print the build process',
617
- default=False,
633
+ default=False, # type: ignore
618
634
  )
619
635
  keep_going: bool = field(
620
636
  FieldMetadata(
621
637
  action='store_true',
622
638
  ),
623
639
  description='Continue building the next app when the current build fails',
624
- default=False,
640
+ default=False, # type: ignore
625
641
  )
626
642
  no_preserve: bool = field(
627
643
  FieldMetadata(
628
644
  action='store_true',
629
645
  ),
630
646
  description='Do not preserve the build directory after a successful build',
631
- default=False,
647
+ default=False, # type: ignore
632
648
  )
633
649
  ignore_warning_strs: t.Optional[t.List[str]] = field(
634
650
  FieldMetadata(
@@ -641,7 +657,7 @@ class BuildArguments(FindBuildArguments):
641
657
  description='space-separated list of patterns. '
642
658
  'Ignore the warnings in the build output that match the patterns',
643
659
  validation_alias=AliasChoices('ignore_warning_strs', 'ignore_warning_str'),
644
- default=None,
660
+ default=None, # type: ignore
645
661
  )
646
662
  ignore_warning_files: t.Optional[t.List[t.Union[str, TextIOWrapper]]] = field(
647
663
  FieldMetadata(
@@ -656,14 +672,14 @@ class BuildArguments(FindBuildArguments):
656
672
  ),
657
673
  description='Path to the files containing the patterns to ignore the warnings in the build output',
658
674
  validation_alias=AliasChoices('ignore_warning_files', 'ignore_warning_file'),
659
- default=None,
675
+ default=None, # type: ignore
660
676
  )
661
677
  copy_sdkconfig: bool = field(
662
678
  FieldMetadata(
663
679
  action='store_true',
664
680
  ),
665
681
  description='Copy the sdkconfig file to the build directory',
666
- default=False,
682
+ default=False, # type: ignore
667
683
  )
668
684
 
669
685
  # Attrs that support placeholders
@@ -675,7 +691,7 @@ class BuildArguments(FindBuildArguments):
675
691
  description='Record size json filepath of the built apps to the specified file. '
676
692
  'Each line is a json string. Can expand placeholders @p',
677
693
  validation_alias=AliasChoices('collect_size_info_filename', 'collect_size_info'),
678
- default=None,
694
+ default=None, # type: ignore
679
695
  exclude=True, # computed field is used
680
696
  )
681
697
  collect_app_info_filename: t.Optional[str] = field(
@@ -686,7 +702,7 @@ class BuildArguments(FindBuildArguments):
686
702
  description='Record serialized app model of the built apps to the specified file. '
687
703
  'Each line is a json string. Can expand placeholders @p',
688
704
  validation_alias=AliasChoices('collect_app_info_filename', 'collect_app_info'),
689
- default=None,
705
+ default=None, # type: ignore
690
706
  exclude=True, # computed field is used
691
707
  )
692
708
  junitxml_filename: t.Optional[str] = field(
@@ -696,7 +712,7 @@ class BuildArguments(FindBuildArguments):
696
712
  ),
697
713
  description='Path to the junitxml file to record the build results. Can expand placeholder @p',
698
714
  validation_alias=AliasChoices('junitxml_filename', 'junitxml'),
699
- default=None,
715
+ default=None, # type: ignore
700
716
  exclude=True, # computed field is used
701
717
  )
702
718
  # used for expanding placeholders
@@ -753,7 +769,7 @@ class DumpManifestShaArguments(GlobalArguments):
753
769
  required=True,
754
770
  ),
755
771
  description='Path to the manifest files which contains the build test rules of the apps',
756
- default=None,
772
+ default=None, # type: ignore
757
773
  )
758
774
 
759
775
  output: t.Optional[str] = field(
@@ -762,7 +778,7 @@ class DumpManifestShaArguments(GlobalArguments):
762
778
  required=True,
763
779
  ),
764
780
  description='Path to the output file to record the sha256 hash of the manifest rules',
765
- default=None,
781
+ default=None, # type: ignore
766
782
  )
767
783
 
768
784
  def model_post_init(self, __context: Any) -> None:
@@ -863,12 +879,20 @@ def add_args_to_obj_doc_as_params(argument_cls: t.Type[GlobalArguments], obj: t.
863
879
  _obj.__doc__ = _doc_str
864
880
 
865
881
 
866
- def apply_config_file(config_file: t.Optional[str]) -> None:
882
+ def apply_config_file(config_file: t.Optional[str] = None, reset: bool = False) -> None:
867
883
  def _subclasses(klass: t.Type[T]) -> t.Set[t.Type[T]]:
868
884
  return set(klass.__subclasses__()).union([s for c in klass.__subclasses__() for s in _subclasses(c)])
869
885
 
870
- if config_file:
871
- BaseArguments.model_config['toml_file'] = str(config_file)
872
- # modify all subclasses
886
+ if reset:
887
+ BaseArguments.CONFIG_FILE_PATH = None
873
888
  for cls in _subclasses(BaseArguments):
874
- cls.model_config['toml_file'] = str(config_file)
889
+ cls.CONFIG_FILE_PATH = None
890
+
891
+ if config_file:
892
+ if os.path.isfile(config_file):
893
+ p = Path(config_file)
894
+ BaseArguments.CONFIG_FILE_PATH = p
895
+ for cls in _subclasses(BaseArguments):
896
+ cls.CONFIG_FILE_PATH = p
897
+ else:
898
+ LOGGER.warning(f'Config file {config_file} does not exist. Ignoring...')
@@ -1,70 +1,25 @@
1
- # SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
1
+ # SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
2
2
  # SPDX-License-Identifier: Apache-2.0
3
3
 
4
4
  import enum
5
- import importlib
6
- import logging
7
5
  import os
8
- import re
9
- import sys
10
- import typing as t
11
6
 
12
- from .utils import (
13
- to_version,
14
- )
7
+ import esp_bool_parser
15
8
 
16
- LOGGER = logging.getLogger(__name__)
17
-
18
- _idf_env = os.getenv('IDF_PATH') or ''
19
- if not _idf_env:
20
- LOGGER.warning('IDF_PATH environment variable is not set. Entering test mode...')
21
- LOGGER.warning('- Setting IDF_PATH to current directory...')
22
- IDF_PATH = os.path.abspath(_idf_env)
9
+ IDF_PATH = esp_bool_parser.IDF_PATH
23
10
  IDF_PY = os.path.join(IDF_PATH, 'tools', 'idf.py')
24
11
  IDF_SIZE_PY = os.path.join(IDF_PATH, 'tools', 'idf_size.py')
12
+
25
13
  PROJECT_DESCRIPTION_JSON = 'project_description.json'
26
14
  DEFAULT_SDKCONFIG = 'sdkconfig.defaults'
27
15
 
28
-
29
- _idf_py_actions = os.path.join(IDF_PATH, 'tools', 'idf_py_actions')
30
- sys.path.append(_idf_py_actions)
31
- try:
32
- _idf_py_constant_py = importlib.import_module('constants')
33
- except ModuleNotFoundError:
34
- LOGGER.warning(
35
- '- Set supported/preview targets to empty list... (ESP-IDF constants.py module not found under %s)',
36
- _idf_py_actions,
37
- )
38
- _idf_py_constant_py = object() # type: ignore
39
- SUPPORTED_TARGETS = getattr(_idf_py_constant_py, 'SUPPORTED_TARGETS', [])
40
- PREVIEW_TARGETS = getattr(_idf_py_constant_py, 'PREVIEW_TARGETS', [])
41
- ALL_TARGETS = SUPPORTED_TARGETS + PREVIEW_TARGETS
42
-
43
-
44
- def _idf_version_from_cmake() -> t.Tuple[int, int, int]:
45
- version_path = os.path.join(IDF_PATH, 'tools', 'cmake', 'version.cmake')
46
- if not os.path.isfile(version_path):
47
- LOGGER.warning('- Setting ESP-IDF version to 1.0.0... (ESP-IDF version.cmake not exists at %s)', version_path)
48
- return 1, 0, 0
49
-
50
- regex = re.compile(r'^\s*set\s*\(\s*IDF_VERSION_([A-Z]{5})\s+(\d+)')
51
- ver = {}
52
- try:
53
- with open(version_path) as f:
54
- for line in f:
55
- m = regex.match(line)
56
-
57
- if m:
58
- ver[m.group(1)] = m.group(2)
59
-
60
- return int(ver['MAJOR']), int(ver['MINOR']), int(ver['PATCH'])
61
- except (KeyError, OSError):
62
- raise ValueError(f'Cannot find ESP-IDF version in {version_path}')
63
-
64
-
65
- IDF_VERSION_MAJOR, IDF_VERSION_MINOR, IDF_VERSION_PATCH = _idf_version_from_cmake()
66
-
67
- IDF_VERSION = to_version(f'{IDF_VERSION_MAJOR}.{IDF_VERSION_MINOR}.{IDF_VERSION_PATCH}')
16
+ SUPPORTED_TARGETS = esp_bool_parser.SUPPORTED_TARGETS
17
+ PREVIEW_TARGETS = esp_bool_parser.PREVIEW_TARGETS
18
+ ALL_TARGETS = esp_bool_parser.ALL_TARGETS
19
+ IDF_VERSION_MAJOR = esp_bool_parser.IDF_VERSION_MAJOR
20
+ IDF_VERSION_MINOR = esp_bool_parser.IDF_VERSION_MINOR
21
+ IDF_VERSION_PATCH = esp_bool_parser.IDF_VERSION_PATCH
22
+ IDF_VERSION = esp_bool_parser.IDF_VERSION
68
23
 
69
24
 
70
25
  class BuildStatus(str, enum.Enum):
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
@@ -28,7 +28,7 @@ def get_processor_name():
28
28
  with open('/proc/cpuinfo') as f:
29
29
  for line in f:
30
30
  if 'model name' in line:
31
- return re.sub('.*model name.*:', '', line, 1).strip()
31
+ return re.sub('.*model name.*:', '', line, count=1).strip()
32
32
  except Exception:
33
33
  pass
34
34
 
idf_build_apps/main.py CHANGED
@@ -1,6 +1,6 @@
1
1
  # PYTHON_ARGCOMPLETE_OK
2
2
 
3
- # SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
3
+ # SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
4
4
  # SPDX-License-Identifier: Apache-2.0
5
5
 
6
6
  import argparse
@@ -68,7 +68,8 @@ def find_apps(
68
68
 
69
69
  :return: list of found apps
70
70
  """
71
- apply_config_file(config_file)
71
+ if config_file:
72
+ apply_config_file(config_file)
72
73
 
73
74
  # compatible with old usage
74
75
  ## `preserve`
@@ -132,7 +133,8 @@ def build_apps(
132
133
 
133
134
  :return: exit code
134
135
  """
135
- apply_config_file(config_file)
136
+ if config_file:
137
+ apply_config_file(config_file)
136
138
 
137
139
  # compatible with old usage
138
140
  ## `check_app_dependencies`
@@ -385,8 +387,8 @@ def main():
385
387
  kwargs = vars(args)
386
388
  action = kwargs.pop('action')
387
389
  config_file = kwargs.pop('config_file')
388
-
389
- apply_config_file(config_file)
390
+ if config_file:
391
+ apply_config_file(config_file)
390
392
 
391
393
  if action == 'dump-manifest-sha':
392
394
  arguments = DumpManifestShaArguments(**drop_none_kwargs(kwargs))
@@ -1,6 +1,17 @@
1
- # SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
1
+ # SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
2
2
  # SPDX-License-Identifier: Apache-2.0
3
3
 
4
4
  """
5
5
  Manifest file
6
6
  """
7
+
8
+ from esp_bool_parser import register_addition_attribute
9
+
10
+ from .manifest import FolderRule
11
+
12
+
13
+ def folder_rule_attr(target, **kwargs):
14
+ return 1 if target in FolderRule.DEFAULT_BUILD_TARGETS else 0
15
+
16
+
17
+ register_addition_attribute('INCLUDE_DEFAULT', folder_rule_attr)