From 1f8ced8e6f1c99c62f1998b265a024022caaa354 Mon Sep 17 00:00:00 2001 From: Frantisek Hrbata Date: Tue, 3 Jun 2025 09:22:53 +0200 Subject: [PATCH 1/2] fix(tools): add support for shells compatible with ksh Currently, the export tools are detecting only ksh, but there are also compatible variants like pdksh and others. This update adds support for such ksh-compatible shells to improve export tool compatibility with ksh variants. Closes https://github.com/espressif/esp-idf/issues/16043 Signed-off-by: Frantisek Hrbata --- tools/export_utils/shell_types.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tools/export_utils/shell_types.py b/tools/export_utils/shell_types.py index cb1f541263..1320fccc3f 100644 --- a/tools/export_utils/shell_types.py +++ b/tools/export_utils/shell_types.py @@ -323,7 +323,16 @@ SHELL_CLASSES = { 'zsh': ZshShell, 'fish': FishShell, 'sh': UnixShell, + + # KornShell variants 'ksh': UnixShell, + 'ksh93': UnixShell, + 'mksh': UnixShell, + 'lksh': UnixShell, + 'pdksh': UnixShell, + 'oksh': UnixShell, + 'loksh': UnixShell, + 'dash': UnixShell, 'nu': UnixShell, 'pwsh.exe': PowerShell, From 28e3112cde393cab4fd5cfe372d998b5bcd9fa8d Mon Sep 17 00:00:00 2001 From: Frantisek Hrbata Date: Tue, 3 Jun 2025 09:26:50 +0200 Subject: [PATCH 2/2] fix(tools): ruff-format changes for shell_types.py Signed-off-by: Frantisek Hrbata --- tools/export_utils/shell_types.py | 90 ++++++++++++++++++------------- 1 file changed, 52 insertions(+), 38 deletions(-) diff --git a/tools/export_utils/shell_types.py b/tools/export_utils/shell_types.py index 1320fccc3f..3dce7eb755 100644 --- a/tools/export_utils/shell_types.py +++ b/tools/export_utils/shell_types.py @@ -10,9 +10,9 @@ from datetime import datetime from datetime import timedelta from pathlib import Path from subprocess import run -from tempfile import gettempdir from tempfile import NamedTemporaryFile from tempfile import TemporaryDirectory +from tempfile import gettempdir from typing import Dict from typing import List from typing import TextIO @@ -26,8 +26,8 @@ from utils import conf from utils import run_cmd -class Shell(): - def __init__(self, shell: str, deactivate_cmd: str, new_esp_idf_env: Dict[str,str]): +class Shell: + def __init__(self, shell: str, deactivate_cmd: str, new_esp_idf_env: Dict[str, str]): self.shell = shell self.deactivate_cmd = deactivate_cmd self.new_esp_idf_env = new_esp_idf_env @@ -79,7 +79,7 @@ class Shell(): class UnixShell(Shell): - def __init__(self, shell: str, deactivate_cmd: str, new_esp_idf_env: Dict[str,str]): + def __init__(self, shell: str, deactivate_cmd: str, new_esp_idf_env: Dict[str, str]): super().__init__(shell, deactivate_cmd, new_esp_idf_env) with NamedTemporaryFile(dir=self.tmp_dir_path, delete=False, prefix='activate_') as fd: @@ -100,8 +100,12 @@ class UnixShell(Shell): stdout = self.autocompletion() # type: ignore if stdout is not None: fd.write(f'{stdout}\n') - fd.write((f'echo "\nDone! You can now compile ESP-IDF projects.\n' - 'Go to the project directory and run:\n\n idf.py build"\n')) + fd.write( + ( + 'echo "\nDone! You can now compile ESP-IDF projects.\n' + 'Go to the project directory and run:\n\n idf.py build"\n' + ) + ) def export(self) -> None: with open(self.script_file_path, 'w', encoding='utf-8') as fd: @@ -195,7 +199,7 @@ class ZshShell(UnixShell): class FishShell(UnixShell): - def __init__(self, shell: str, deactivate_cmd: str, new_esp_idf_env: Dict[str,str]): + def __init__(self, shell: str, deactivate_cmd: str, new_esp_idf_env: Dict[str, str]): super().__init__(shell, deactivate_cmd, new_esp_idf_env) self.new_esp_idf_env['IDF_TOOLS_INSTALL_CMD'] = os.path.join(conf.IDF_PATH, 'install.fish') self.new_esp_idf_env['IDF_TOOLS_EXPORT_CMD'] = os.path.join(conf.IDF_PATH, 'export.fish') @@ -219,7 +223,7 @@ class FishShell(UnixShell): class PowerShell(Shell): - def __init__(self, shell: str, deactivate_cmd: str, new_esp_idf_env: Dict[str,str]): + def __init__(self, shell: str, deactivate_cmd: str, new_esp_idf_env: Dict[str, str]): super().__init__(shell, deactivate_cmd, new_esp_idf_env) with NamedTemporaryFile(dir=self.tmp_dir_path, delete=False, prefix='activate_', suffix='.ps1') as fd: @@ -230,14 +234,16 @@ class PowerShell(Shell): self.new_esp_idf_env['IDF_TOOLS_EXPORT_CMD'] = os.path.join(conf.IDF_PATH, 'export.ps1') def get_functions(self) -> str: - return '\n'.join([ - r'function idf.py { &python "$Env:IDF_PATH\tools\idf.py" $args }', - r'function global:esptool.py { &python -m esptool $args }', - r'function global:espefuse.py { &python -m espefuse $args }', - r'function global:espsecure.py { &python -m espsecure $args }', - r'function global:otatool.py { &python "$Env:IDF_PATH\components\app_update\otatool.py" $args }', - r'function global:parttool.py { &python "$Env:IDF_PATH\components\partition_table\parttool.py" $args }', - ]) + return '\n'.join( + [ + r'function idf.py { &python "$Env:IDF_PATH\tools\idf.py" $args }', + r'function global:esptool.py { &python -m esptool $args }', + r'function global:espefuse.py { &python -m espefuse $args }', + r'function global:espsecure.py { &python -m espsecure $args }', + r'function global:otatool.py { &python "$Env:IDF_PATH\components\app_update\otatool.py" $args }', + r'function global:parttool.py { &python "$Env:IDF_PATH\components\partition_table\parttool.py" $args }', + ] + ) def export(self) -> None: self.init_file() @@ -254,8 +260,12 @@ class PowerShell(Shell): fd.write(f'$Env:{var}="{value}"\n') functions = self.get_functions() fd.write(f'{functions}\n') - fd.write((f'echo "\nDone! You can now compile ESP-IDF projects.\n' - 'Go to the project directory and run:\n\n idf.py build\n"')) + fd.write( + ( + 'echo "\nDone! You can now compile ESP-IDF projects.\n' + 'Go to the project directory and run:\n\n idf.py build\n"' + ) + ) def spawn(self) -> None: self.init_file() @@ -266,7 +276,7 @@ class PowerShell(Shell): class WinCmd(Shell): - def __init__(self, shell: str, deactivate_cmd: str, new_esp_idf_env: Dict[str,str]): + def __init__(self, shell: str, deactivate_cmd: str, new_esp_idf_env: Dict[str, str]): super().__init__(shell, deactivate_cmd, new_esp_idf_env) with NamedTemporaryFile(dir=self.tmp_dir_path, delete=False, prefix='activate_', suffix='.bat') as fd: @@ -279,14 +289,16 @@ class WinCmd(Shell): self.new_esp_idf_env['IDF_TOOLS_PY_PATH'] = conf.IDF_TOOLS_PY def get_functions(self) -> str: - return '\n'.join([ - r'DOSKEY idf.py=python.exe "%IDF_PATH%\tools\idf.py" $*', - r'DOSKEY esptool.py=python.exe -m esptool $*', - r'DOSKEY espefuse.py=python.exe -m espefuse $*', - r'DOSKEY espsecure.py=python.exe -m espsecure $*', - r'DOSKEY otatool.py=python.exe "%IDF_PATH%\components\app_update\otatool.py" $*', - r'DOSKEY parttool.py=python.exe "%IDF_PATH%\components\partition_table\parttool.py" $*', - ]) + return '\n'.join( + [ + r'DOSKEY idf.py=python.exe "%IDF_PATH%\tools\idf.py" $*', + r'DOSKEY esptool.py=python.exe -m esptool $*', + r'DOSKEY espefuse.py=python.exe -m espefuse $*', + r'DOSKEY espsecure.py=python.exe -m espsecure $*', + r'DOSKEY otatool.py=python.exe "%IDF_PATH%\components\app_update\otatool.py" $*', + r'DOSKEY parttool.py=python.exe "%IDF_PATH%\components\partition_table\parttool.py" $*', + ] + ) def export(self) -> None: self.init_file() @@ -300,14 +312,18 @@ class WinCmd(Shell): fd.write(f'set {var}={value}\n') functions = self.get_functions() fd.write(f'{functions}\n') - fd.write('\n'.join([ - 'echo.', - 'echo Done! You can now compile ESP-IDF projects.', - 'echo Go to the project directory and run:', - 'echo.', - 'echo idf.py build', - 'echo.', - ])) + fd.write( + '\n'.join( + [ + 'echo.', + 'echo Done! You can now compile ESP-IDF projects.', + 'echo Go to the project directory and run:', + 'echo.', + 'echo idf.py build', + 'echo.', + ] + ) + ) def spawn(self) -> None: self.init_file() @@ -323,7 +339,6 @@ SHELL_CLASSES = { 'zsh': ZshShell, 'fish': FishShell, 'sh': UnixShell, - # KornShell variants 'ksh': UnixShell, 'ksh93': UnixShell, @@ -332,7 +347,6 @@ SHELL_CLASSES = { 'pdksh': UnixShell, 'oksh': UnixShell, 'loksh': UnixShell, - 'dash': UnixShell, 'nu': UnixShell, 'pwsh.exe': PowerShell, @@ -340,7 +354,7 @@ SHELL_CLASSES = { 'powershell.exe': PowerShell, 'powershell': PowerShell, 'cmd.exe': WinCmd, - 'cmd': WinCmd + 'cmd': WinCmd, } SUPPORTED_SHELLS = ' '.join(SHELL_CLASSES.keys())