forked from espressif/esp-idf
feat(idf_tools): Switch from global variables to global singleton
This commit is contained in:
@@ -302,18 +302,53 @@ DL_CERT_DICT = {'dl.espressif.com': DIGICERT_ROOT_G2_CERT,
|
|||||||
'github.com': DIGICERT_ROOT_CA_CERT}
|
'github.com': DIGICERT_ROOT_CA_CERT}
|
||||||
|
|
||||||
|
|
||||||
global_quiet: bool = False
|
class GlobalVarsStore:
|
||||||
global_non_interactive: bool = False
|
"""
|
||||||
global_idf_path: Optional[str] = None
|
Pythonic way how to handle global variables.
|
||||||
global_idf_tools_path: Optional[str] = None
|
One global instance of this class is initialized and used as an entrypoint (store)
|
||||||
global_tools_json: Optional[str] = None
|
It handles string and boolean properties.
|
||||||
|
"""
|
||||||
|
_instance: Optional['GlobalVarsStore'] = None
|
||||||
|
_bool_properties = ['quiet', 'non_interactive']
|
||||||
|
_string_properties = ['idf_path', 'idf_tools_path', 'tools_json']
|
||||||
|
|
||||||
|
def __new__(cls, *args: Any, **kwargs: Any) -> 'GlobalVarsStore':
|
||||||
|
if not cls._instance:
|
||||||
|
cls._instance = super(GlobalVarsStore, cls).__new__(cls, *args, **kwargs)
|
||||||
|
cls._instance._initialize_properties()
|
||||||
|
return cls._instance
|
||||||
|
|
||||||
|
def _initialize_properties(self) -> None:
|
||||||
|
# Initialize boolean properties to False
|
||||||
|
for prop in self._bool_properties:
|
||||||
|
setattr(self, f'_{prop}', False)
|
||||||
|
# Initialize string properties to None
|
||||||
|
for prop in self._string_properties:
|
||||||
|
setattr(self, f'_{prop}', None)
|
||||||
|
|
||||||
|
def __getattr__(self, name: str) -> Any:
|
||||||
|
if name in self._bool_properties + self._string_properties:
|
||||||
|
value: Union[str, bool] = getattr(self, f'_{name}')
|
||||||
|
if value is None and name in self._string_properties:
|
||||||
|
raise ReferenceError(f'Variable {name} accessed before initialization.')
|
||||||
|
return value
|
||||||
|
raise AttributeError(f'{name} is not a valid attribute')
|
||||||
|
|
||||||
|
def __setattr__(self, name: str, value: Any) -> None:
|
||||||
|
if name in self._bool_properties + self._string_properties:
|
||||||
|
super().__setattr__(f'_{name}', value)
|
||||||
|
else:
|
||||||
|
super().__setattr__(name, value)
|
||||||
|
|
||||||
|
|
||||||
|
g = GlobalVarsStore()
|
||||||
|
|
||||||
|
|
||||||
def fatal(text: str, *args: str) -> None:
|
def fatal(text: str, *args: str) -> None:
|
||||||
"""
|
"""
|
||||||
Writes ERROR: + text to sys.stderr.
|
Writes ERROR: + text to sys.stderr.
|
||||||
"""
|
"""
|
||||||
if not global_quiet:
|
if not g.quiet:
|
||||||
sys.stderr.write('ERROR: ' + text + '\n', *args)
|
sys.stderr.write('ERROR: ' + text + '\n', *args)
|
||||||
|
|
||||||
|
|
||||||
@@ -321,7 +356,7 @@ def warn(text: str, *args: str) -> None:
|
|||||||
"""
|
"""
|
||||||
Writes WARNING: + text to sys.stderr.
|
Writes WARNING: + text to sys.stderr.
|
||||||
"""
|
"""
|
||||||
if not global_quiet:
|
if not g.quiet:
|
||||||
sys.stderr.write('WARNING: ' + text + '\n', *args)
|
sys.stderr.write('WARNING: ' + text + '\n', *args)
|
||||||
|
|
||||||
|
|
||||||
@@ -329,7 +364,7 @@ def info(text: str, f: Optional[IO[str]]=None, *args: str) -> None:
|
|||||||
"""
|
"""
|
||||||
Writes text to a stream specified by second arg, sys.stdout by default.
|
Writes text to a stream specified by second arg, sys.stdout by default.
|
||||||
"""
|
"""
|
||||||
if not global_quiet:
|
if not g.quiet:
|
||||||
if f is None:
|
if f is None:
|
||||||
f = sys.stdout
|
f = sys.stdout
|
||||||
f.write(text + '\n', *args)
|
f.write(text + '\n', *args)
|
||||||
@@ -568,7 +603,7 @@ def download(url: str, destination: str) -> Union[None, Exception]:
|
|||||||
else:
|
else:
|
||||||
ctx = None
|
ctx = None
|
||||||
|
|
||||||
urlretrieve_ctx(url, destination, report_progress if not global_non_interactive else None, context=ctx)
|
urlretrieve_ctx(url, destination, report_progress if not g.non_interactive else None, context=ctx)
|
||||||
sys.stdout.write('\rDone\n')
|
sys.stdout.write('\rDone\n')
|
||||||
return None
|
return None
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -813,7 +848,7 @@ class IDFTool(object):
|
|||||||
"""
|
"""
|
||||||
Returns path where the tool is installed.
|
Returns path where the tool is installed.
|
||||||
"""
|
"""
|
||||||
return os.path.join(global_idf_tools_path or '', 'tools', self.name)
|
return os.path.join(g.idf_tools_path, 'tools', self.name)
|
||||||
|
|
||||||
def get_path_for_version(self, version: str) -> str:
|
def get_path_for_version(self, version: str) -> str:
|
||||||
"""
|
"""
|
||||||
@@ -949,7 +984,7 @@ class IDFTool(object):
|
|||||||
|
|
||||||
def find_installed_versions(self) -> None:
|
def find_installed_versions(self) -> None:
|
||||||
"""
|
"""
|
||||||
Checks whether the tool can be found in PATH and in global_idf_tools_path.
|
Checks whether the tool can be found in PATH and in GlobalVarsStore.idf_tools_path.
|
||||||
Writes results to self.version_in_path and self.versions_installed.
|
Writes results to self.version_in_path and self.versions_installed.
|
||||||
|
|
||||||
Raises ToolBinaryError if an error occurred when running any version of the tool.
|
Raises ToolBinaryError if an error occurred when running any version of the tool.
|
||||||
@@ -970,7 +1005,7 @@ class IDFTool(object):
|
|||||||
else:
|
else:
|
||||||
self.version_in_path = ver_str
|
self.version_in_path = ver_str
|
||||||
|
|
||||||
# Now check all the versions installed in global_idf_tools_path
|
# Now check all the versions installed in GlobalVarsStore.idf_tools_path
|
||||||
self.versions_installed = []
|
self.versions_installed = []
|
||||||
for version, version_obj in self.versions.items():
|
for version, version_obj in self.versions.items():
|
||||||
if not version_obj.compatible_with_platform():
|
if not version_obj.compatible_with_platform():
|
||||||
@@ -1037,7 +1072,7 @@ class IDFTool(object):
|
|||||||
|
|
||||||
url = download_obj.url
|
url = download_obj.url
|
||||||
archive_name = download_obj.rename_dist if download_obj.rename_dist else os.path.basename(url)
|
archive_name = download_obj.rename_dist if download_obj.rename_dist else os.path.basename(url)
|
||||||
local_path = os.path.join(global_idf_tools_path or '', 'dist', archive_name)
|
local_path = os.path.join(g.idf_tools_path, 'dist', archive_name)
|
||||||
mkdir_p(os.path.dirname(local_path))
|
mkdir_p(os.path.dirname(local_path))
|
||||||
|
|
||||||
if os.path.isfile(local_path):
|
if os.path.isfile(local_path):
|
||||||
@@ -1075,7 +1110,7 @@ class IDFTool(object):
|
|||||||
download_obj = self.versions[version].get_download_for_platform(self._platform)
|
download_obj = self.versions[version].get_download_for_platform(self._platform)
|
||||||
assert download_obj is not None
|
assert download_obj is not None
|
||||||
archive_name = download_obj.rename_dist if download_obj.rename_dist else os.path.basename(download_obj.url)
|
archive_name = download_obj.rename_dist if download_obj.rename_dist else os.path.basename(download_obj.url)
|
||||||
archive_path = os.path.join(global_idf_tools_path or '', 'dist', archive_name)
|
archive_path = os.path.join(g.idf_tools_path, 'dist', archive_name)
|
||||||
assert os.path.isfile(archive_path)
|
assert os.path.isfile(archive_path)
|
||||||
dest_dir = self.get_path_for_version(version)
|
dest_dir = self.get_path_for_version(version)
|
||||||
if os.path.exists(dest_dir):
|
if os.path.exists(dest_dir):
|
||||||
@@ -1383,7 +1418,7 @@ class IDFRecord:
|
|||||||
def get_active_idf_record(cls) -> 'IDFRecord':
|
def get_active_idf_record(cls) -> 'IDFRecord':
|
||||||
idf_record_obj = cls()
|
idf_record_obj = cls()
|
||||||
idf_record_obj.version = get_idf_version()
|
idf_record_obj.version = get_idf_version()
|
||||||
idf_record_obj.path = global_idf_path or ''
|
idf_record_obj.path = g.idf_path
|
||||||
return idf_record_obj
|
return idf_record_obj
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@@ -1430,17 +1465,18 @@ class IDFEnv:
|
|||||||
"""
|
"""
|
||||||
# It is enough to compare just active records because others can't be touched by the running script
|
# It is enough to compare just active records because others can't be touched by the running script
|
||||||
if self.get_active_idf_record() != self.get_idf_env().get_active_idf_record():
|
if self.get_active_idf_record() != self.get_idf_env().get_active_idf_record():
|
||||||
idf_env_file_path = os.path.join(global_idf_tools_path or '', IDF_ENV_FILE)
|
idf_env_file_path = os.path.join(g.idf_tools_path, IDF_ENV_FILE)
|
||||||
try:
|
try:
|
||||||
if global_idf_tools_path: # mypy fix for Optional[str] in the next call
|
if g.idf_tools_path: # mypy fix for Optional[str] in the next call
|
||||||
# the directory doesn't exist if this is run on a clean system the first time
|
# the directory doesn't exist if this is run on a clean system the first time
|
||||||
mkdir_p(global_idf_tools_path)
|
mkdir_p(g.idf_tools_path)
|
||||||
with open(idf_env_file_path, 'w', encoding='utf-8') as w:
|
with open(idf_env_file_path, 'w', encoding='utf-8') as w:
|
||||||
info('Updating {}'.format(idf_env_file_path))
|
info('Updating {}'.format(idf_env_file_path))
|
||||||
json.dump(dict(self), w, cls=IDFEnvEncoder, ensure_ascii=False, indent=4) # type: ignore
|
json.dump(dict(self), w, cls=IDFEnvEncoder, ensure_ascii=False, indent=4) # type: ignore
|
||||||
except (IOError, OSError):
|
except (IOError, OSError):
|
||||||
if not os.access(global_idf_tools_path or '', os.W_OK):
|
if not os.access(g.idf_tools_path, os.W_OK):
|
||||||
raise OSError('IDF_TOOLS_PATH {} is not accessible to write. Required changes have not been saved'.format(global_idf_tools_path or ''))
|
raise OSError('IDF_TOOLS_PATH {} is not accessible to write.\
|
||||||
|
Required changes have not been saved'.format(g.idf_tools_path))
|
||||||
raise OSError('File {} is not accessible to write or corrupted. Required changes have not been saved'.format(idf_env_file_path))
|
raise OSError('File {} is not accessible to write or corrupted. Required changes have not been saved'.format(idf_env_file_path))
|
||||||
|
|
||||||
def get_active_idf_record(self) -> IDFRecord:
|
def get_active_idf_record(self) -> IDFRecord:
|
||||||
@@ -1453,7 +1489,7 @@ class IDFEnv:
|
|||||||
"""
|
"""
|
||||||
idf_env_obj = cls()
|
idf_env_obj = cls()
|
||||||
try:
|
try:
|
||||||
idf_env_file_path = os.path.join(global_idf_tools_path or '', IDF_ENV_FILE)
|
idf_env_file_path = os.path.join(g.idf_tools_path, IDF_ENV_FILE)
|
||||||
with open(idf_env_file_path, 'r', encoding='utf-8') as idf_env_file:
|
with open(idf_env_file_path, 'r', encoding='utf-8') as idf_env_file:
|
||||||
idf_env_json = json.load(idf_env_file)
|
idf_env_json = json.load(idf_env_file)
|
||||||
|
|
||||||
@@ -1530,7 +1566,8 @@ def load_tools_info() -> Dict[str, IDFTool]:
|
|||||||
"""
|
"""
|
||||||
Load tools metadata from tools.json, return a dictionary: tool name - tool info.
|
Load tools metadata from tools.json, return a dictionary: tool name - tool info.
|
||||||
"""
|
"""
|
||||||
tool_versions_file_name = global_tools_json
|
|
||||||
|
tool_versions_file_name = g.tools_json
|
||||||
|
|
||||||
with open(tool_versions_file_name, 'r') as f: # type: ignore
|
with open(tool_versions_file_name, 'r') as f: # type: ignore
|
||||||
tools_info = json.load(f)
|
tools_info = json.load(f)
|
||||||
@@ -1590,7 +1627,7 @@ def get_idf_version() -> str:
|
|||||||
"""
|
"""
|
||||||
Return ESP-IDF version.
|
Return ESP-IDF version.
|
||||||
"""
|
"""
|
||||||
version_file_path = os.path.join(global_idf_path, 'version.txt') # type: ignore
|
version_file_path = os.path.join(g.idf_path, 'version.txt') # type: ignore
|
||||||
if os.path.exists(version_file_path):
|
if os.path.exists(version_file_path):
|
||||||
with open(version_file_path, 'r') as version_file:
|
with open(version_file_path, 'r') as version_file:
|
||||||
idf_version_str = version_file.read()
|
idf_version_str = version_file.read()
|
||||||
@@ -1598,7 +1635,7 @@ def get_idf_version() -> str:
|
|||||||
idf_version_str = ''
|
idf_version_str = ''
|
||||||
try:
|
try:
|
||||||
idf_version_str = subprocess.check_output(['git', 'describe'],
|
idf_version_str = subprocess.check_output(['git', 'describe'],
|
||||||
cwd=global_idf_path, env=os.environ,
|
cwd=g.idf_path, env=os.environ,
|
||||||
stderr=subprocess.DEVNULL).decode()
|
stderr=subprocess.DEVNULL).decode()
|
||||||
except OSError:
|
except OSError:
|
||||||
# OSError should cover FileNotFoundError and WindowsError
|
# OSError should cover FileNotFoundError and WindowsError
|
||||||
@@ -1614,7 +1651,7 @@ def get_idf_version() -> str:
|
|||||||
idf_version = None
|
idf_version = None
|
||||||
# fallback when IDF is a shallow clone
|
# fallback when IDF is a shallow clone
|
||||||
try:
|
try:
|
||||||
with open(os.path.join(global_idf_path, 'components', 'esp_common', 'include', 'esp_idf_version.h')) as f: # type: ignore
|
with open(os.path.join(g.idf_path, 'components', 'esp_common', 'include', 'esp_idf_version.h')) as f: # type: ignore
|
||||||
m = re.search(r'^#define\s+ESP_IDF_VERSION_MAJOR\s+(\d+).+?^#define\s+ESP_IDF_VERSION_MINOR\s+(\d+)',
|
m = re.search(r'^#define\s+ESP_IDF_VERSION_MAJOR\s+(\d+).+?^#define\s+ESP_IDF_VERSION_MINOR\s+(\d+)',
|
||||||
f.read(), re.DOTALL | re.MULTILINE)
|
f.read(), re.DOTALL | re.MULTILINE)
|
||||||
if m:
|
if m:
|
||||||
@@ -1638,7 +1675,7 @@ def get_python_env_path() -> Tuple[str, str, str, str]:
|
|||||||
python_ver_major_minor = '{}.{}'.format(sys.version_info.major, sys.version_info.minor)
|
python_ver_major_minor = '{}.{}'.format(sys.version_info.major, sys.version_info.minor)
|
||||||
|
|
||||||
idf_version = get_idf_version()
|
idf_version = get_idf_version()
|
||||||
idf_python_env_path = os.getenv('IDF_PYTHON_ENV_PATH') or os.path.join(global_idf_tools_path or '', 'python_env',
|
idf_python_env_path = os.getenv('IDF_PYTHON_ENV_PATH') or os.path.join(g.idf_tools_path, 'python_env',
|
||||||
'idf{}_py{}_env'.format(idf_version, python_ver_major_minor))
|
'idf{}_py{}_env'.format(idf_version, python_ver_major_minor))
|
||||||
|
|
||||||
python_exe, subdir = get_python_exe_and_subdir()
|
python_exe, subdir = get_python_exe_and_subdir()
|
||||||
@@ -1716,7 +1753,7 @@ def feature_to_requirements_path(feature: str) -> str:
|
|||||||
"""
|
"""
|
||||||
Convert feature (ci, core, docs, gdbgui, pytest, ...) to the path to its requirements.txt.
|
Convert feature (ci, core, docs, gdbgui, pytest, ...) to the path to its requirements.txt.
|
||||||
"""
|
"""
|
||||||
return os.path.join(global_idf_path or '', 'tools', 'requirements', 'requirements.{}.txt'.format(feature))
|
return os.path.join(g.idf_path, 'tools', 'requirements', 'requirements.{}.txt'.format(feature))
|
||||||
|
|
||||||
|
|
||||||
def process_and_check_features(idf_env_obj: IDFEnv, features_str: str) -> List[str]:
|
def process_and_check_features(idf_env_obj: IDFEnv, features_str: str) -> List[str]:
|
||||||
@@ -1843,7 +1880,7 @@ def different_idf_detected() -> bool:
|
|||||||
"""
|
"""
|
||||||
# If IDF global variable found, test if belong to different ESP-IDF version
|
# If IDF global variable found, test if belong to different ESP-IDF version
|
||||||
if 'IDF_TOOLS_EXPORT_CMD' in os.environ:
|
if 'IDF_TOOLS_EXPORT_CMD' in os.environ:
|
||||||
if global_idf_path != os.path.dirname(os.environ['IDF_TOOLS_EXPORT_CMD']):
|
if g.idf_path != os.path.dirname(os.environ['IDF_TOOLS_EXPORT_CMD']):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
# No previous ESP-IDF export detected, nothing to be unset
|
# No previous ESP-IDF export detected, nothing to be unset
|
||||||
@@ -1863,9 +1900,11 @@ def active_repo_id() -> str:
|
|||||||
Function returns unique id of running ESP-IDF combining current idfpath with version.
|
Function returns unique id of running ESP-IDF combining current idfpath with version.
|
||||||
The id is unique with same version & different path or same path & different version.
|
The id is unique with same version & different path or same path & different version.
|
||||||
"""
|
"""
|
||||||
if global_idf_path is None:
|
try:
|
||||||
|
# g.idf_path is forcefully casted to str just to make type linters happy
|
||||||
|
return str(g.idf_path) + '-v' + get_idf_version()
|
||||||
|
except ReferenceError:
|
||||||
return 'UNKNOWN_PATH' + '-v' + get_idf_version()
|
return 'UNKNOWN_PATH' + '-v' + get_idf_version()
|
||||||
return global_idf_path + '-v' + get_idf_version()
|
|
||||||
|
|
||||||
|
|
||||||
def list_default(args): # type: ignore
|
def list_default(args): # type: ignore
|
||||||
@@ -2115,7 +2154,7 @@ def action_export(args: Any) -> None:
|
|||||||
if os.getenv('ESP_IDF_VERSION') != idf_version:
|
if os.getenv('ESP_IDF_VERSION') != idf_version:
|
||||||
export_vars['ESP_IDF_VERSION'] = idf_version
|
export_vars['ESP_IDF_VERSION'] = idf_version
|
||||||
|
|
||||||
idf_tools_dir = os.path.join(global_idf_path, 'tools') # type: ignore
|
idf_tools_dir = os.path.join(g.idf_path, 'tools') # type: ignore
|
||||||
idf_tools_dir = to_shell_specific_paths([idf_tools_dir])[0]
|
idf_tools_dir = to_shell_specific_paths([idf_tools_dir])[0]
|
||||||
if current_path and idf_tools_dir not in current_path:
|
if current_path and idf_tools_dir not in current_path:
|
||||||
paths_to_export.append(idf_tools_dir)
|
paths_to_export.append(idf_tools_dir)
|
||||||
@@ -2221,8 +2260,8 @@ def get_tools_spec_and_platform_info(selected_platform: str, targets: List[str],
|
|||||||
"""
|
"""
|
||||||
global global_quiet
|
global global_quiet
|
||||||
try:
|
try:
|
||||||
old_global_quiet = global_quiet
|
old_global_quiet = g.quiet
|
||||||
global_quiet = quiet
|
g.quiet = quiet
|
||||||
tools_info = load_tools_info()
|
tools_info = load_tools_info()
|
||||||
tools_info_for_platform = OrderedDict()
|
tools_info_for_platform = OrderedDict()
|
||||||
for name, tool_obj in tools_info.items():
|
for name, tool_obj in tools_info.items():
|
||||||
@@ -2232,7 +2271,7 @@ def get_tools_spec_and_platform_info(selected_platform: str, targets: List[str],
|
|||||||
tools_spec = expand_tools_arg(tools_spec, tools_info_for_platform, targets)
|
tools_spec = expand_tools_arg(tools_spec, tools_info_for_platform, targets)
|
||||||
info('Downloading tools for {}: {}'.format(selected_platform, ', '.join(tools_spec)))
|
info('Downloading tools for {}: {}'.format(selected_platform, ', '.join(tools_spec)))
|
||||||
finally:
|
finally:
|
||||||
global_quiet = old_global_quiet
|
g.quiet = old_global_quiet
|
||||||
|
|
||||||
return tools_spec, tools_info_for_platform
|
return tools_spec, tools_info_for_platform
|
||||||
|
|
||||||
@@ -2396,7 +2435,7 @@ def get_constraints(idf_version: str, online: bool = True) -> str:
|
|||||||
"""
|
"""
|
||||||
idf_download_url = get_idf_download_url_apply_mirrors()
|
idf_download_url = get_idf_download_url_apply_mirrors()
|
||||||
constraint_file = 'espidf.constraints.v{}.txt'.format(idf_version)
|
constraint_file = 'espidf.constraints.v{}.txt'.format(idf_version)
|
||||||
constraint_path = os.path.join(global_idf_tools_path or '', constraint_file)
|
constraint_path = os.path.join(g.idf_tools_path, constraint_file)
|
||||||
constraint_url = '/'.join([idf_download_url, constraint_file])
|
constraint_url = '/'.join([idf_download_url, constraint_file])
|
||||||
temp_path = constraint_path + '.tmp'
|
temp_path = constraint_path + '.tmp'
|
||||||
|
|
||||||
@@ -2612,7 +2651,7 @@ def action_check_python_dependencies(args): # type: ignore
|
|||||||
# The dependency checker will be invoked with virtualenv_python. idf_tools.py could have been invoked with a
|
# The dependency checker will be invoked with virtualenv_python. idf_tools.py could have been invoked with a
|
||||||
# different one, therefore, importing is not a suitable option.
|
# different one, therefore, importing is not a suitable option.
|
||||||
dep_check_cmd = [virtualenv_python,
|
dep_check_cmd = [virtualenv_python,
|
||||||
os.path.join(global_idf_path,
|
os.path.join(g.idf_path,
|
||||||
'tools',
|
'tools',
|
||||||
'check_python_dependencies.py')]
|
'check_python_dependencies.py')]
|
||||||
|
|
||||||
@@ -2662,7 +2701,7 @@ class ChecksumFileParser():
|
|||||||
def __init__(self, tool_name: str, url: str) -> None:
|
def __init__(self, tool_name: str, url: str) -> None:
|
||||||
self.tool_name = tool_name
|
self.tool_name = tool_name
|
||||||
|
|
||||||
sha256_file_tmp = os.path.join(global_idf_tools_path or '', 'tools', 'add-version.sha256.tmp')
|
sha256_file_tmp = os.path.join(g.idf_tools_path, 'tools', 'add-version.sha256.tmp')
|
||||||
sha256_file = os.path.abspath(url)
|
sha256_file = os.path.abspath(url)
|
||||||
|
|
||||||
# download sha256 file if URL presented
|
# download sha256 file if URL presented
|
||||||
@@ -2747,7 +2786,7 @@ def action_add_version(args: Any) -> None:
|
|||||||
version_obj.add_download(found_platform, url, file_size, file_sha256)
|
version_obj.add_download(found_platform, url, file_size, file_sha256)
|
||||||
json_str = dump_tools_json(tools_info)
|
json_str = dump_tools_json(tools_info)
|
||||||
if not args.output:
|
if not args.output:
|
||||||
args.output = os.path.join(global_idf_path, TOOLS_FILE_NEW) # type: ignore
|
args.output = os.path.join(g.idf_path, TOOLS_FILE_NEW) # type: ignore
|
||||||
with open(args.output, 'w') as f:
|
with open(args.output, 'w') as f:
|
||||||
f.write(json_str)
|
f.write(json_str)
|
||||||
f.write('\n')
|
f.write('\n')
|
||||||
@@ -2761,7 +2800,7 @@ def action_rewrite(args): # type: ignore
|
|||||||
tools_info = load_tools_info()
|
tools_info = load_tools_info()
|
||||||
json_str = dump_tools_json(tools_info)
|
json_str = dump_tools_json(tools_info)
|
||||||
if not args.output:
|
if not args.output:
|
||||||
args.output = os.path.join(global_idf_path, TOOLS_FILE_NEW)
|
args.output = os.path.join(g.idf_path, TOOLS_FILE_NEW)
|
||||||
with open(args.output, 'w') as f:
|
with open(args.output, 'w') as f:
|
||||||
f.write(json_str)
|
f.write(json_str)
|
||||||
f.write('\n')
|
f.write('\n')
|
||||||
@@ -2774,8 +2813,8 @@ def action_uninstall(args: Any) -> None:
|
|||||||
Additionally remove all older versions of previously downloaded archives.
|
Additionally remove all older versions of previously downloaded archives.
|
||||||
"""
|
"""
|
||||||
tools_info = load_tools_info()
|
tools_info = load_tools_info()
|
||||||
tools_path = os.path.join(global_idf_tools_path or '', 'tools')
|
tools_path = os.path.join(g.idf_tools_path, 'tools')
|
||||||
dist_path = os.path.join(global_idf_tools_path or '', 'dist')
|
dist_path = os.path.join(g.idf_tools_path, 'dist')
|
||||||
installed_tools = os.listdir(tools_path) if os.path.isdir(tools_path) else []
|
installed_tools = os.listdir(tools_path) if os.path.isdir(tools_path) else []
|
||||||
|
|
||||||
unused_tools_versions = {}
|
unused_tools_versions = {}
|
||||||
@@ -2798,7 +2837,7 @@ def action_uninstall(args: Any) -> None:
|
|||||||
if args.dry_run:
|
if args.dry_run:
|
||||||
if unused_tools_versions:
|
if unused_tools_versions:
|
||||||
print('For removing old versions of {} use command \'{} {} {}\''.format(', '.join(unused_tools_versions), get_python_exe_and_subdir()[0],
|
print('For removing old versions of {} use command \'{} {} {}\''.format(', '.join(unused_tools_versions), get_python_exe_and_subdir()[0],
|
||||||
os.path.join(global_idf_path or '', 'tools', 'idf_tools.py'), 'uninstall'))
|
os.path.join(g.idf_path, 'tools', 'idf_tools.py'), 'uninstall'))
|
||||||
return
|
return
|
||||||
|
|
||||||
# Remove installed tools that are not used by current ESP-IDF version.
|
# Remove installed tools that are not used by current ESP-IDF version.
|
||||||
@@ -2855,10 +2894,10 @@ def action_validate(args): # type: ignore
|
|||||||
fatal('You need to install jsonschema package to use validate command')
|
fatal('You need to install jsonschema package to use validate command')
|
||||||
raise SystemExit(1)
|
raise SystemExit(1)
|
||||||
|
|
||||||
with open(os.path.join(global_idf_path, TOOLS_FILE), 'r') as tools_file:
|
with open(os.path.join(g.idf_path, TOOLS_FILE), 'r') as tools_file:
|
||||||
tools_json = json.load(tools_file)
|
tools_json = json.load(tools_file)
|
||||||
|
|
||||||
with open(os.path.join(global_idf_path, TOOLS_SCHEMA_FILE), 'r') as schema_file:
|
with open(os.path.join(g.idf_path, TOOLS_SCHEMA_FILE), 'r') as schema_file:
|
||||||
schema_json = json.load(schema_file)
|
schema_json = json.load(schema_file)
|
||||||
jsonschema.validate(tools_json, schema_json)
|
jsonschema.validate(tools_json, schema_json)
|
||||||
# on failure, this will raise an exception with a fairly verbose diagnostic message
|
# on failure, this will raise an exception with a fairly verbose diagnostic message
|
||||||
@@ -3098,26 +3137,22 @@ def main(argv: List[str]) -> None:
|
|||||||
parser.exit(1)
|
parser.exit(1)
|
||||||
|
|
||||||
if args.quiet:
|
if args.quiet:
|
||||||
global global_quiet
|
g.quiet = True
|
||||||
global_quiet = True
|
|
||||||
|
|
||||||
if args.non_interactive:
|
if args.non_interactive:
|
||||||
global global_non_interactive
|
g.non_interactive = True
|
||||||
global_non_interactive = True
|
|
||||||
|
|
||||||
if 'unset' in args and args.unset:
|
if 'unset' in args and args.unset:
|
||||||
args.deactivate = True
|
args.deactivate = True
|
||||||
|
|
||||||
global global_idf_path
|
g.idf_path = os.environ.get('IDF_PATH') # type: ignore
|
||||||
global_idf_path = os.environ.get('IDF_PATH')
|
|
||||||
if args.idf_path:
|
if args.idf_path:
|
||||||
global_idf_path = args.idf_path
|
g.idf_path = args.idf_path
|
||||||
if not global_idf_path:
|
if not g.idf_path:
|
||||||
global_idf_path = os.path.realpath(os.path.join(os.path.dirname(__file__), '..'))
|
g.idf_path = os.path.realpath(os.path.join(os.path.dirname(__file__), '..'))
|
||||||
os.environ['IDF_PATH'] = global_idf_path
|
os.environ['IDF_PATH'] = g.idf_path
|
||||||
|
|
||||||
global global_idf_tools_path
|
g.idf_tools_path = os.environ.get('IDF_TOOLS_PATH') or os.path.expanduser(IDF_TOOLS_PATH_DEFAULT)
|
||||||
global_idf_tools_path = os.environ.get('IDF_TOOLS_PATH') or os.path.expanduser(IDF_TOOLS_PATH_DEFAULT)
|
|
||||||
|
|
||||||
# On macOS, unset __PYVENV_LAUNCHER__ variable if it is set.
|
# On macOS, unset __PYVENV_LAUNCHER__ variable if it is set.
|
||||||
# Otherwise sys.executable keeps pointing to the system Python, even when a python binary from a virtualenv is invoked.
|
# Otherwise sys.executable keeps pointing to the system Python, even when a python binary from a virtualenv is invoked.
|
||||||
@@ -3126,9 +3161,9 @@ def main(argv: List[str]) -> None:
|
|||||||
|
|
||||||
if sys.version_info.major == 2:
|
if sys.version_info.major == 2:
|
||||||
try:
|
try:
|
||||||
global_idf_tools_path.decode('ascii') # type: ignore
|
g.idf_tools_path.decode('ascii') # type: ignore
|
||||||
except UnicodeDecodeError:
|
except UnicodeDecodeError:
|
||||||
fatal('IDF_TOOLS_PATH contains non-ASCII characters: {}'.format(global_idf_tools_path) +
|
fatal('IDF_TOOLS_PATH contains non-ASCII characters: {}'.format(g.idf_tools_path) +
|
||||||
'\nThis is not supported yet with Python 2. ' +
|
'\nThis is not supported yet with Python 2. ' +
|
||||||
'Please set IDF_TOOLS_PATH to a directory with an ASCII name, or switch to Python 3.')
|
'Please set IDF_TOOLS_PATH to a directory with an ASCII name, or switch to Python 3.')
|
||||||
raise SystemExit(1)
|
raise SystemExit(1)
|
||||||
@@ -3137,11 +3172,10 @@ def main(argv: List[str]) -> None:
|
|||||||
fatal('Platform {} appears to be unsupported'.format(PYTHON_PLATFORM))
|
fatal('Platform {} appears to be unsupported'.format(PYTHON_PLATFORM))
|
||||||
raise SystemExit(1)
|
raise SystemExit(1)
|
||||||
|
|
||||||
global global_tools_json
|
|
||||||
if args.tools_json:
|
if args.tools_json:
|
||||||
global_tools_json = args.tools_json
|
g.tools_json = args.tools_json
|
||||||
else:
|
else:
|
||||||
global_tools_json = os.path.join(global_idf_path, TOOLS_FILE)
|
g.tools_json = os.path.join(g.idf_path, TOOLS_FILE)
|
||||||
|
|
||||||
action_func_name = 'action_' + args.action.replace('-', '_')
|
action_func_name = 'action_' + args.action.replace('-', '_')
|
||||||
action_func = globals()[action_func_name]
|
action_func = globals()[action_func_name]
|
||||||
|
@@ -37,8 +37,8 @@ CONSTR = 'Constraint file: {}'.format(os.path.join(TOOLS_DIR, 'espidf.constraint
|
|||||||
# Set default global paths for idf_tools. If some test needs to
|
# Set default global paths for idf_tools. If some test needs to
|
||||||
# use functions from idf_tools with custom paths, it should
|
# use functions from idf_tools with custom paths, it should
|
||||||
# set it in setUp() and change them back to defaults in tearDown().
|
# set it in setUp() and change them back to defaults in tearDown().
|
||||||
idf_tools.global_idf_path = IDF_PATH
|
idf_tools.g.idf_path = IDF_PATH
|
||||||
idf_tools.global_idf_tools_path = TOOLS_DIR
|
idf_tools.g.idf_tools_path = TOOLS_DIR
|
||||||
|
|
||||||
|
|
||||||
def setUpModule(): # type: () -> None
|
def setUpModule(): # type: () -> None
|
||||||
|
Reference in New Issue
Block a user