1+ #!/usr/bin/env python3
12import time
23import sys
34import subprocess
1516MIN_ESPTOOL_VERSION = "5.2.0"
1617DEFAULT_BAUD = 460800 # Original default; can be overridden via CLI
1718REQUIRED_FILES = ["bootloader.bin" , "partition-table.bin" , "projectZero.bin" ]
19+ SCRIPT_DIR = os .path .dirname (os .path .abspath (__file__ ))
20+ VENV_DIR = os .environ .get ("FLASH_BOARD_VENV" , os .path .join (SCRIPT_DIR , ".venv" ))
1821
1922def parse_version (version ):
2023 parts = []
@@ -47,6 +50,48 @@ def get_esptool_version(esptool_module):
4750 pass
4851 return getattr (esptool_module , "__version__" , None )
4952
53+ def in_virtualenv ():
54+ return (
55+ getattr (sys , "base_prefix" , sys .prefix ) != sys .prefix
56+ or getattr (sys , "real_prefix" , None ) is not None
57+ )
58+
59+ def get_venv_python (venv_dir = VENV_DIR ):
60+ if os .name == "nt" :
61+ return os .path .join (venv_dir , "Scripts" , "python.exe" )
62+ return os .path .join (venv_dir , "bin" , "python" )
63+
64+ def create_local_venv (venv_dir = VENV_DIR ):
65+ venv_python = get_venv_python (venv_dir )
66+ if os .path .exists (venv_python ):
67+ return venv_python
68+ print (f"{ YELLOW } Creating local virtual environment: { venv_dir } { RESET } " )
69+ try :
70+ subprocess .check_call ([sys .executable , "-m" , "venv" , venv_dir ])
71+ except subprocess .CalledProcessError :
72+ print (f"{ RED } Failed to create virtual environment at { venv_dir } .{ RESET } " )
73+ print (f"{ YELLOW } Install Python venv support (for Debian/Ubuntu: apt install python3-venv) and retry.{ RESET } " )
74+ sys .exit (1 )
75+ return venv_python
76+
77+ def ensure_pip (python_executable ):
78+ probe = subprocess .run (
79+ [python_executable , "-m" , "pip" , "--version" ],
80+ stdout = subprocess .DEVNULL ,
81+ stderr = subprocess .DEVNULL ,
82+ )
83+ if probe .returncode == 0 :
84+ return
85+ subprocess .check_call ([python_executable , "-m" , "ensurepip" , "--upgrade" ])
86+
87+ def install_with_python (python_executable , packages ):
88+ ensure_pip (python_executable )
89+ print (f"{ YELLOW } Installing/upgrading packages: { ', ' .join (packages )} { RESET } " )
90+ subprocess .check_call ([python_executable , "-m" , "pip" , "install" , "--upgrade" ] + packages )
91+
92+ def reexec_with_python (python_executable ):
93+ os .execv (python_executable , [python_executable ] + sys .argv )
94+
5095def ensure_packages ():
5196 missing = []
5297 try :
@@ -62,9 +107,9 @@ def ensure_packages():
62107 if not installed_version or not is_version_at_least (installed_version , MIN_ESPTOOL_VERSION ):
63108 missing .append (f"esptool>={ MIN_ESPTOOL_VERSION } " )
64109 if missing :
65- print ( f" { YELLOW } Installing/upgrading packages: { ', ' . join ( missing ) } { RESET } " )
66- subprocess . check_call ([ sys . executable , "-m" , "pip" , "install" , "--upgrade" ] + missing )
67- os . execv ( sys . executable , [ sys . executable ] + sys . argv )
110+ target_python = sys . executable if in_virtualenv () else create_local_venv ( )
111+ install_with_python ( target_python , missing )
112+ reexec_with_python ( target_python )
68113
69114ensure_packages ()
70115import serial
0 commit comments