@@ -113,6 +113,30 @@ def build_installer_7zip(
113113 except subprocess .CalledProcessError as e :
114114 print (f"Error executing 7-Zip script: { e } " , file = sys .stderr )
115115
116+ def _copy_items (source_dirs : list [Path ], target_dir : Path , verbose : bool = False ):
117+ """
118+ Copies items from source directories to the target directory.
119+
120+ Args:
121+ source_dirs: List of source directories to copy items from.
122+ target_dir: Target directory to copy items to.
123+ verbose: Enable verbose output.
124+ """
125+ target_dir .mkdir (parents = True , exist_ok = True )
126+ for source_dir in source_dirs :
127+ if not source_dir .is_dir ():
128+ print (f"Warning: Source directory not found: { source_dir } " )
129+ continue
130+ for item_name in os .listdir (source_dir ):
131+ source_item = source_dir / item_name
132+ target_item = target_dir / item_name
133+ copy_func = shutil .copytree if source_item .is_dir () else shutil .copy2
134+ try :
135+ copy_func (source_item , target_item )
136+ if verbose :
137+ print (f" Copied: { source_item } -> { target_item } " )
138+ except Exception as e :
139+ print (f"Error copying { source_item } to { target_item } : { e } " )
116140
117141class WinPythonDistributionBuilder :
118142 """
@@ -434,26 +458,11 @@ def _extract_python_archive(self):
434458 if self .python_dir_name != self .python_name and not python_target_dir .is_dir ():
435459 os .rename (self .winpy_dir / self .python_name , python_target_dir )
436460
437-
438461 def _copy_tools (self ):
439462 """Copies development tools to the WinPython 't' directory."""
440463 tools_target_dir = self .winpy_dir / "t"
441464 self ._print_action (f"Copying tools to { tools_target_dir } " )
442- tools_target_dir .mkdir (parents = True , exist_ok = True )
443- for source_dir in self .tools_directories :
444- if not source_dir .is_dir ():
445- print (f"Warning: Tools directory not found: { source_dir } " )
446- continue
447- for item_name in os .listdir (source_dir ):
448- source_item = source_dir / item_name
449- target_item = tools_target_dir / item_name
450- copy_func = shutil .copytree if source_item .is_dir () else shutil .copy2
451- try :
452- copy_func (source_item , target_item )
453- if self .verbose :
454- print (f" Copied: { source_item } -> { target_item } " )
455- except Exception as e :
456- print (f"Error copying { source_item } to { target_item } : { e } " )
465+ _copy_items (self .tools_directories , tools_target_dir , self .verbose )
457466
458467 # Special handling for Node.js to move it up one level
459468 nodejs_current_dir = tools_target_dir / "n"
@@ -463,53 +472,29 @@ def _copy_tools(self):
463472 shutil .move (nodejs_current_dir , nodejs_target_dir )
464473 except Exception as e :
465474 print (f"Error moving Node.js directory: { e } " )
466-
467475 self ._print_action_done ()
468476
469-
470477 def _copy_documentation (self ):
471478 """Copies documentation files to the WinPython 'docs' directory."""
472479 docs_target_dir = self .winpy_dir / "notebooks" / "docs"
473480 self ._print_action (f"Copying documentation to { docs_target_dir } " )
474- docs_target_dir .mkdir (parents = True , exist_ok = True )
475- for source_dir in self .docs_directories :
476- if not source_dir .is_dir ():
477- print (f"Warning: Documentation directory not found: { source_dir } " )
478- continue
479- for item_name in os .listdir (source_dir ):
480- source_item = source_dir / item_name
481- target_item = docs_target_dir / item_name
482- copy_func = shutil .copytree if source_item .is_dir () else shutil .copy2
483- try :
484- copy_func (source_item , target_item )
485- if self .verbose :
486- print (f" Copied: { source_item } -> { target_item } " )
487- except Exception as e :
488- print (f"Error copying { source_item } to { target_item } : { e } " )
481+ _copy_items (self .docs_directories , docs_target_dir , self .verbose )
489482 self ._print_action_done ()
490483
491-
492484 def _copy_launchers (self ):
493485 """Copies pre-made launchers to the WinPython directory."""
494486 self ._print_action ("Creating launchers" )
495487 launchers_source_dir = PORTABLE_DIR / "launchers_final"
496- for item in launchers_source_dir .rglob ('*.exe' ):
497- shutil .copy2 (item , self .winpy_dir )
498- if self .verbose :
499- print (f" Copied launcher: { item .name } -> { self .winpy_dir } " )
500- for item in launchers_source_dir .rglob ('licence*.*' ):
501- shutil .copy2 (item , self .winpy_dir )
488+ _copy_items ([launchers_source_dir ], self .winpy_dir , self .verbose )
502489 self ._print_action_done ()
503490
504491 def _copy_default_scripts (self ):
505492 """Copies launchers and defeult scripts."""
506493 self ._print_action ("copying pre-made scripts" )
507494 origin = PORTABLE_DIR / "scripts"
508495 destination = self .winpy_dir / "scripts"
509- for item in origin .rglob ('*.*' ):
510- shutil .copy2 (item , destination )
511- if self .verbose :
512- print (f" Copied : { item .name } -> { destination } " )
496+ _copy_items ([origin ], destination , self .verbose )
497+ self ._print_action_done ()
513498
514499 def _create_initial_batch_scripts (self ):
515500 """Creates initial batch scripts, including environment setup."""
0 commit comments