2424import json
2525import subprocess
2626import sys
27+ import shutil
2728import os
2829import pkg_resources
2930
5859
5960# Required until Arduino switches to v5
6061IDF5 = platform .get_package_version ("framework-espidf" ).split ("." )[1 ].startswith ("5" )
62+ IDF_ENV_VERSION = "1.0.0"
6163FRAMEWORK_DIR = platform .get_package_dir ("framework-espidf" )
6264TOOLCHAIN_DIR = platform .get_package_dir (
6365 "toolchain-%s" % ("riscv32-esp" if mcu == "esp32c3" else ("xtensa-%s" % mcu ))
@@ -1147,40 +1149,71 @@ def _get_installed_pip_packages(python_exe_path):
11471149 )
11481150 )
11491151
1152+ def get_idf_venv_dir ():
1153+ # The name of the IDF venv contains the IDF version to avoid possible conflicts and
1154+ # unnecessary reinstallation of Python dependencies in cases when Arduino
1155+ # as an IDF component requires a different version of the IDF package and
1156+ # hence a different set of Python deps or their versions
1157+ idf_version = get_original_version (platform .get_package_version ("framework-espidf" ))
1158+ return os .path .join (
1159+ env .subst ("$PROJECT_CORE_DIR" ), "penv" , ".espidf-" + idf_version
1160+ )
1161+
1162+ def ensure_python_venv_available ():
1163+
1164+ def _is_venv_outdated (venv_data_file ):
1165+ try :
1166+ with open (venv_data_file , "r" , encoding = "utf8" ) as fp :
1167+ venv_data = json .load (fp )
1168+ if venv_data .get ("version" , "" ) != IDF_ENV_VERSION :
1169+ return True
1170+ return False
1171+ except :
1172+ return True
11501173
1151- def get_python_exe ():
11521174 def _create_venv (venv_dir ):
11531175 pip_path = os .path .join (
11541176 venv_dir ,
11551177 "Scripts" if IS_WINDOWS else "bin" ,
11561178 "pip" + (".exe" if IS_WINDOWS else "" ),
11571179 )
1158- if not os .path .isfile (pip_path ):
1180+
1181+ if os .path .isdir (venv_dir ):
1182+ try :
1183+ print ("Removing an oudated IDF virtual environment" )
1184+ shutil .rmtree (venv_dir )
1185+ except OSError :
1186+ print (
1187+ "Error: Cannot remove an outdated IDF virtual environment. " \
1188+ "Please remove the `%s` folder manually!" % venv_dir
1189+ )
1190+ env .Exit (1 )
1191+
11591192 # Use the built-in PlatformIO Python to create a standalone IDF virtual env
11601193 env .Execute (
11611194 env .VerboseAction (
11621195 '"$PYTHONEXE" -m venv --clear "%s"' % venv_dir ,
1163- "Creating a virtual environment for IDF Python dependencies" ,
1196+ "Creating a new virtual environment for IDF Python dependencies" ,
11641197 )
11651198 )
11661199
11671200 assert os .path .isfile (
11681201 pip_path
1169- ), "Error: Failed to create a proper virtual environment. Missing the pip binary!"
1202+ ), "Error: Failed to create a proper virtual environment. Missing the ` pip` binary!"
11701203
1171- # The name of the IDF venv contains the IDF version to avoid possible conflicts and
1172- # unnecessary reinstallation of Python dependencies in cases when Arduino
1173- # as an IDF component requires a different version of the IDF package and
1174- # hence a different set of Python deps or their versions
1175- idf_version = get_original_version (platform .get_package_version ("framework-espidf" ))
1176- venv_dir = os .path .join (
1177- env .subst ("$PROJECT_CORE_DIR" ), "penv" , ".espidf-" + idf_version )
11781204
1179- if not os .path .isdir (venv_dir ):
1205+ venv_dir = get_idf_venv_dir ()
1206+ venv_data_file = os .path .join (venv_dir , "pio-idf-venv.json" )
1207+ if not os .path .isfile (venv_data_file ) or _is_venv_outdated (venv_data_file ):
11801208 _create_venv (venv_dir )
1209+ with open (venv_data_file , "w" , encoding = "utf8" ) as fp :
1210+ venv_info = {"version" : IDF_ENV_VERSION }
1211+ json .dump (venv_info , fp , indent = 2 )
1212+
11811213
1214+ def get_python_exe ():
11821215 python_exe_path = os .path .join (
1183- venv_dir ,
1216+ get_idf_venv_dir () ,
11841217 "Scripts" if IS_WINDOWS else "bin" ,
11851218 "python" + (".exe" if IS_WINDOWS else "" ),
11861219 )
@@ -1196,6 +1229,7 @@ def _create_venv(venv_dir):
11961229# ESP-IDF requires Python packages with specific versions in a virtual environment
11971230#
11981231
1232+ ensure_python_venv_available ()
11991233install_python_deps ()
12001234
12011235# ESP-IDF package doesn't contain .git folder, instead package version is specified
0 commit comments