9
9
10
10
11
11
class ComponentManager :
12
- """Manages IDF components for ESP32 Arduino framework builds."""
12
+ """Manages IDF components for ESP32 Arduino framework builds with logging support ."""
13
13
14
14
def __init__ (self , env ):
15
+ """
16
+ Initialize the ComponentManager.
17
+
18
+ Args:
19
+ env: PlatformIO environment object
20
+ """
15
21
self .env = env
16
22
self .platform = env .PioPlatform ()
17
23
self .config = env .GetProjectConfig ()
@@ -21,15 +27,35 @@ def __init__(self, env):
21
27
self .removed_components : Set [str ] = set ()
22
28
self .ignored_libs : Set [str ] = set ()
23
29
30
+ # Simple logging attributes
31
+ self .component_changes : List [str ] = []
32
+
24
33
self .arduino_framework_dir = self .platform .get_package_dir ("framework-arduinoespressif32" )
25
34
self .arduino_libs_mcu = join (self .platform .get_package_dir ("framework-arduinoespressif32-libs" ), self .mcu )
35
+
36
+ def _log_change (self , message : str ) -> None :
37
+ """
38
+ Simple logging without timestamp.
39
+
40
+ Args:
41
+ message: Log message to record
42
+ """
43
+ self .component_changes .append (message )
44
+ print (f"[ComponentManager] { message } " )
26
45
27
46
def handle_component_settings (self , add_components : bool = False , remove_components : bool = False ) -> None :
28
- """Handle adding and removing IDF components based on project configuration."""
47
+ """
48
+ Handle adding and removing IDF components based on project configuration.
49
+
50
+ Args:
51
+ add_components: Whether to process component additions
52
+ remove_components: Whether to process component removals
53
+ """
29
54
30
55
# Create backup before first component removal
31
56
if remove_components and not self .removed_components or add_components and not self .add_components :
32
57
self ._backup_pioarduino_build_py ()
58
+ self ._log_change ("Created backup of build file" )
33
59
34
60
# Check if env and GetProjectOption are available
35
61
if hasattr (self , 'env' ) or hasattr (self .env , 'GetProjectOption' ):
@@ -43,9 +69,7 @@ def handle_component_settings(self, add_components: bool = False, remove_compone
43
69
components_to_remove = remove_option .splitlines ()
44
70
self ._remove_components (component_data , components_to_remove )
45
71
except Exception as e :
46
- # Optional: Logging for debugging
47
- # print(f"Error removing components: {e}")
48
- pass
72
+ self ._log_change (f"Error removing components: { str (e )} " )
49
73
50
74
if add_components :
51
75
try :
@@ -54,9 +78,7 @@ def handle_component_settings(self, add_components: bool = False, remove_compone
54
78
components_to_add = add_option .splitlines ()
55
79
self ._add_components (component_data , components_to_add )
56
80
except Exception as e :
57
- # Optional: Logging for debugging
58
- # print(f"Error adding components: {e}")
59
- pass
81
+ self ._log_change (f"Error adding components: { str (e )} " )
60
82
61
83
self ._save_component_yml (component_yml_path , component_data )
62
84
@@ -65,6 +87,10 @@ def handle_component_settings(self, add_components: bool = False, remove_compone
65
87
self ._cleanup_removed_components ()
66
88
67
89
self .handle_lib_ignore ()
90
+
91
+ # Print summary
92
+ if self .component_changes :
93
+ self ._log_change (f"Session completed with { len (self .component_changes )} changes" )
68
94
69
95
def handle_lib_ignore (self ) -> None :
70
96
"""Handle lib_ignore entries from platformio.ini and remove corresponding includes."""
@@ -78,10 +104,15 @@ def handle_lib_ignore(self) -> None:
78
104
if lib_ignore_entries :
79
105
self .ignored_libs .update (lib_ignore_entries )
80
106
self ._remove_ignored_lib_includes ()
81
- print (f"Removed include paths for { len (lib_ignore_entries )} ignored libraries" )
107
+ self . _log_change (f"Processed { len (lib_ignore_entries )} ignored libraries" )
82
108
83
109
def _get_lib_ignore_entries (self ) -> List [str ]:
84
- """Get lib_ignore entries from current environment configuration only."""
110
+ """
111
+ Get lib_ignore entries from current environment configuration only.
112
+
113
+ Returns:
114
+ List of library names to ignore
115
+ """
85
116
try :
86
117
# Get lib_ignore from current environment only
87
118
lib_ignore = self .env .GetProjectOption ("lib_ignore" , [])
@@ -236,7 +267,12 @@ def _is_component_used_in_project(self, lib_name: str) -> bool:
236
267
return False
237
268
238
269
def _get_arduino_core_libraries (self ) -> Dict [str , str ]:
239
- """Get all Arduino core libraries and their corresponding include paths."""
270
+ """
271
+ Get all Arduino core libraries and their corresponding include paths.
272
+
273
+ Returns:
274
+ Dictionary mapping library names to include paths
275
+ """
240
276
libraries_mapping = {}
241
277
242
278
# Path to Arduino Core Libraries
@@ -260,7 +296,15 @@ def _get_arduino_core_libraries(self) -> Dict[str, str]:
260
296
return libraries_mapping
261
297
262
298
def _get_library_name_from_properties (self , lib_dir : str ) -> Optional [str ]:
263
- """Extract library name from library.properties file."""
299
+ """
300
+ Extract library name from library.properties file.
301
+
302
+ Args:
303
+ lib_dir: Library directory path
304
+
305
+ Returns:
306
+ Library name or None if not found
307
+ """
264
308
prop_path = join (lib_dir , "library.properties" )
265
309
if not os .path .isfile (prop_path ):
266
310
return None
@@ -277,7 +321,16 @@ def _get_library_name_from_properties(self, lib_dir: str) -> Optional[str]:
277
321
return None
278
322
279
323
def _map_library_to_include_path (self , lib_name : str , dir_name : str ) -> str :
280
- """Map library name to corresponding include path."""
324
+ """
325
+ Map library name to corresponding include path.
326
+
327
+ Args:
328
+ lib_name: Library name
329
+ dir_name: Directory name
330
+
331
+ Returns:
332
+ Mapped include path
333
+ """
281
334
lib_name_lower = lib_name .lower ().replace (' ' , '' ).replace ('-' , '_' )
282
335
dir_name_lower = dir_name .lower ()
283
336
@@ -434,7 +487,7 @@ def _remove_ignored_lib_includes(self) -> None:
434
487
for lib_name in self .ignored_libs :
435
488
# Universal protection: Skip if component is actually used in project
436
489
if self ._is_component_used_in_project (lib_name ):
437
- print (f"Skipping removal of library '{ lib_name } ' - detected as used in project" )
490
+ self . _log_change (f"Skipping removal of library '{ lib_name } ' - detected as used in project" )
438
491
continue
439
492
440
493
# Multiple patterns to catch different include formats
@@ -454,6 +507,7 @@ def _remove_ignored_lib_includes(self) -> None:
454
507
if matches :
455
508
content = re .sub (pattern , '' , content )
456
509
total_removed += len (matches )
510
+ self ._log_change (f"Removed { len (matches )} include entries for library '{ lib_name } '" )
457
511
458
512
# Clean up empty lines and trailing commas
459
513
content = re .sub (r'\n\s*\n' , '\n ' , content )
@@ -463,9 +517,10 @@ def _remove_ignored_lib_includes(self) -> None:
463
517
if self ._validate_changes (original_content , content ) and content != original_content :
464
518
with open (build_py_path , 'w' ) as f :
465
519
f .write (content )
520
+ self ._log_change (f"Successfully updated build file with { total_removed } total removals" )
466
521
467
- except Exception :
468
- pass
522
+ except Exception as e :
523
+ self . _log_change ( f"Error processing ignored library includes: { str ( e ) } " )
469
524
470
525
def _validate_changes (self , original_content : str , new_content : str ) -> bool :
471
526
"""Validate that the changes are reasonable."""
@@ -492,13 +547,15 @@ def _get_or_create_component_yml(self) -> str:
492
547
493
548
# Create new file in project source
494
549
self ._create_default_component_yml (project_yml )
550
+ self ._log_change (f"Created new component.yml file at { project_yml } " )
495
551
return project_yml
496
552
497
553
def _create_backup (self , file_path : str ) -> None :
498
554
"""Create backup of a file."""
499
555
backup_path = f"{ file_path } .orig"
500
556
if not os .path .exists (backup_path ):
501
557
shutil .copy (file_path , backup_path )
558
+ self ._log_change (f"Created backup: { backup_path } " )
502
559
503
560
def _create_default_component_yml (self , file_path : str ) -> None :
504
561
"""Create a default idf_component.yml file."""
@@ -524,8 +581,9 @@ def _save_component_yml(self, file_path: str, data: Dict[str, Any]) -> None:
524
581
try :
525
582
with open (file_path , "w" ) as f :
526
583
yaml .dump (data , f )
527
- except Exception :
528
- pass
584
+ self ._log_change (f"Saved component configuration to { file_path } " )
585
+ except Exception as e :
586
+ self ._log_change (f"Error saving component configuration: { str (e )} " )
529
587
530
588
def _remove_components (self , component_data : Dict [str , Any ], components_to_remove : list ) -> None :
531
589
"""Remove specified components from the configuration."""
@@ -538,6 +596,7 @@ def _remove_components(self, component_data: Dict[str, Any], components_to_remov
538
596
539
597
if component in dependencies :
540
598
del dependencies [component ]
599
+ self ._log_change (f"Removed component: { component } " )
541
600
542
601
# Track for cleanup
543
602
filesystem_name = self ._convert_component_name_to_filesystem (component )
@@ -556,6 +615,7 @@ def _add_components(self, component_data: Dict[str, Any], components_to_add: lis
556
615
557
616
if component_name not in dependencies :
558
617
dependencies [component_name ] = {"version" : version }
618
+ self ._log_change (f"Added component: { component_name } (version: { version } )" )
559
619
560
620
def _parse_component_entry (self , entry : str ) -> tuple [str , str ]:
561
621
"""Parse component entry into name and version."""
@@ -578,6 +638,7 @@ def _backup_pioarduino_build_py(self) -> None:
578
638
579
639
if os .path .exists (build_py_path ) and not os .path .exists (backup_path ):
580
640
shutil .copy2 (build_py_path , backup_path )
641
+ self ._log_change (f"Created backup of pioarduino-build.py for { self .mcu } " )
581
642
582
643
def _cleanup_removed_components (self ) -> None :
583
644
"""Clean up removed components and restore original build file."""
@@ -592,6 +653,7 @@ def _remove_include_directory(self, component: str) -> None:
592
653
593
654
if os .path .exists (include_path ):
594
655
shutil .rmtree (include_path )
656
+ self ._log_change (f"Removed include directory: { include_path } " )
595
657
596
658
def _remove_cpppath_entries (self ) -> None :
597
659
"""Remove CPPPATH entries for removed components from pioarduino-build.py."""
@@ -620,9 +682,10 @@ def _remove_cpppath_entries(self) -> None:
620
682
if content != original_content :
621
683
with open (build_py_path , 'w' ) as f :
622
684
f .write (content )
685
+ self ._log_change (f"Cleaned up CPPPATH entries for removed components" )
623
686
624
- except Exception :
625
- pass
687
+ except Exception as e :
688
+ self . _log_change ( f"Error cleaning up CPPPATH entries: { str ( e ) } " )
626
689
627
690
def restore_pioarduino_build_py (self , source = None , target = None , env = None ) -> None :
628
691
"""Restore the original pioarduino-build.py from backup."""
@@ -632,3 +695,4 @@ def restore_pioarduino_build_py(self, source=None, target=None, env=None) -> Non
632
695
if os .path .exists (backup_path ):
633
696
shutil .copy2 (backup_path , build_py_path )
634
697
os .remove (backup_path )
698
+ self ._log_change ("Restored original pioarduino-build.py from backup" )
0 commit comments