From ac4a3af777c741d33747081235a05530ea54072c Mon Sep 17 00:00:00 2001 From: Ali Azam Rana <85216275+alirana01@users.noreply.github.com> Date: Thu, 23 Apr 2026 11:03:08 +0200 Subject: [PATCH 1/3] EIM Path discovery improvements --- .../idf/core/tools/ToolInitializer.java | 65 ++++++++++++++++--- .../idf/ui/tools/EspressifToolStartup.java | 33 ++++------ 2 files changed, 68 insertions(+), 30 deletions(-) diff --git a/bundles/com.espressif.idf.core/src/com/espressif/idf/core/tools/ToolInitializer.java b/bundles/com.espressif.idf.core/src/com/espressif/idf/core/tools/ToolInitializer.java index b577bbc1c..6448edc3d 100644 --- a/bundles/com.espressif.idf.core/src/com/espressif/idf/core/tools/ToolInitializer.java +++ b/bundles/com.espressif.idf.core/src/com/espressif/idf/core/tools/ToolInitializer.java @@ -22,6 +22,7 @@ import com.espressif.idf.core.IDFCorePlugin; import com.espressif.idf.core.IDFEnvironmentVariables; import com.espressif.idf.core.ProcessBuilderFactory; +import com.espressif.idf.core.SystemExecutableFinder; import com.espressif.idf.core.logging.Logger; import com.espressif.idf.core.tools.exceptions.EimVersionMismatchException; import com.espressif.idf.core.tools.vo.EimJson; @@ -48,17 +49,64 @@ public ToolInitializer(Preferences preferences) public boolean isEimInstalled() { + if (!StringUtil.isEmpty(findEimOnSystemPath())) + { + return true; + } + String eimExePathEnv = idfEnvironmentVariables.getEnvValue(IDFEnvironmentVariables.EIM_PATH); boolean exists = !StringUtil.isEmpty(eimExePathEnv) && Files.exists(Paths.get(eimExePathEnv)); if (!exists) { - // Fallback: check in user home .espressif/eim_gui folder - Path defaultEimPath = getDefaultEimPath(); - if (defaultEimPath != null) - exists = Files.exists(defaultEimPath); + // Fallback: well-known install locations (e.g. user home .espressif/eim_gui, /Applications on macOS) + Path defaultEimPath = getDefaultEimPath(); + if (defaultEimPath != null) + { + exists = Files.exists(defaultEimPath); + } } return exists; } + + /** + * Looks for an {@code eim} executable on the process {@code PATH}, using the same rules as other tools in this + * plugin ({@link SystemExecutableFinder}: PATHEXT on Windows, plain name on Linux/macOS). + * + * @return absolute path to the executable, or empty if not found + */ + private String findEimOnSystemPath() + { + IPath eimPath = new SystemExecutableFinder().find("eim"); //$NON-NLS-1$ + return eimPath != null ? eimPath.toOSString() : StringUtil.EMPTY; + } + + /** + * Resolves the EIM executable path: system {@code PATH} first, then {@code eimPath} from + * {@code eim_idf.json} when the path exists on disk, then {@link #getDefaultEimPath()}. + * + * @param eimJson parsed JSON or {@code null} + * @return resolved absolute path string, or empty if nothing could be resolved + */ + public String resolveEimExecutablePath(EimJson eimJson) + { + String fromPath = findEimOnSystemPath(); + if (!StringUtil.isEmpty(fromPath)) + { + return fromPath; + } + + if (eimJson != null && !StringUtil.isEmpty(eimJson.getEimPath())) + { + String jsonPath = eimJson.getEimPath(); + if (Files.exists(Paths.get(jsonPath))) + { + return jsonPath; + } + } + + Path defaultEimPath = getDefaultEimPath(); + return defaultEimPath != null ? defaultEimPath.toString() : StringUtil.EMPTY; + } public boolean isEimIdfJsonPresent() { @@ -162,10 +210,11 @@ else if (os.equals(Platform.OS_MACOSX)) public void findAndSetEimPath() { - Path defaultEimPath = getDefaultEimPath(); - - if (defaultEimPath != null) - setEimPathInEnvVar(defaultEimPath.toString()); + String resolved = resolveEimExecutablePath(null); + if (!StringUtil.isEmpty(resolved)) + { + setEimPathInEnvVar(resolved); + } } private void setEimPathInEnvVar(String eimPath) diff --git a/bundles/com.espressif.idf.ui/src/com/espressif/idf/ui/tools/EspressifToolStartup.java b/bundles/com.espressif.idf.ui/src/com/espressif/idf/ui/tools/EspressifToolStartup.java index 9874bb8d9..bebc7e914 100644 --- a/bundles/com.espressif.idf.ui/src/com/espressif/idf/ui/tools/EspressifToolStartup.java +++ b/bundles/com.espressif.idf.ui/src/com/espressif/idf/ui/tools/EspressifToolStartup.java @@ -115,15 +115,11 @@ else if (toolInitializer.isEimIdfJsonPresent() && !toolInitializer.isEspIdfSet() promptUserToOpenToolManager(eimJson); } - // Set EimPath on every startup to ensure proper path in configurations - if (eimJson != null) + // Set EimPath on every startup: system PATH first, then eim_idf.json, then default locations + String resolvedEimPath = toolInitializer.resolveEimExecutablePath(eimJson); + if (!StringUtil.isEmpty(resolvedEimPath)) { - idfEnvironmentVariables.addEnvVariable(IDFEnvironmentVariables.EIM_PATH, eimJson.getEimPath()); - } - else - { - // Fail-safe call to ensure if the eim is in Applications or user.home it is setup in env vars - toolInitializer.findAndSetEimPath(); + idfEnvironmentVariables.addEnvVariable(IDFEnvironmentVariables.EIM_PATH, resolvedEimPath); } } @@ -163,22 +159,15 @@ private void startExportOldConfig() { try { - // if eim json is present it means that it contains the updated path and we use that else we fallback to - // finding eim in default paths - Path eimPath; - String eimPathEnvVar = idfEnvironmentVariables.getEnvValue(IDFEnvironmentVariables.EIM_PATH); - if (eimJson != null) + // Same resolution order as workspace EIM_PATH: PATH, then eim_idf.json, then defaults + String resolved = toolInitializer.resolveEimExecutablePath(eimJson); + if (StringUtil.isEmpty(resolved)) { - eimPath = Paths.get(eimJson.getEimPath()); - } - else if (!StringUtil.isEmpty(eimPathEnvVar)) - { - eimPath = Paths.get(eimPathEnvVar); - } - else - { - eimPath = toolInitializer.getDefaultEimPath(); + Logger.log("Cannot export old config: EIM executable path could not be resolved."); //$NON-NLS-1$ + writeToErrorConsoleStream(Messages.OldConfigExportCompleteFailMsg); + return; } + Path eimPath = Paths.get(resolved); IStatus status = toolInitializer.exportOldConfig(eimPath); Logger.log("Tools Conversion Process Message: "); From 86bda3030d5b16ce5b2f02f25f9d2ed96f68a46d Mon Sep 17 00:00:00 2001 From: Ali Azam Rana <85216275+alirana01@users.noreply.github.com> Date: Tue, 5 May 2026 11:58:27 +0200 Subject: [PATCH 2/3] Fix EIM path resolver: existence-check defaults, remove dead code - resolveEimExecutablePath now validates default path exists before returning it, preventing bogus EIM_PATH when EIM is not installed - Added EIM_PATH env variable as fallback step in resolution - Unified isEimInstalled() to delegate to resolveEimExecutablePath - Removed dead findAndSetEimPath() and setEimPathInEnvVar() methods --- .../idf/core/tools/ToolInitializer.java | 47 ++++++------------- 1 file changed, 15 insertions(+), 32 deletions(-) diff --git a/bundles/com.espressif.idf.core/src/com/espressif/idf/core/tools/ToolInitializer.java b/bundles/com.espressif.idf.core/src/com/espressif/idf/core/tools/ToolInitializer.java index 6448edc3d..6a6f64531 100644 --- a/bundles/com.espressif.idf.core/src/com/espressif/idf/core/tools/ToolInitializer.java +++ b/bundles/com.espressif.idf.core/src/com/espressif/idf/core/tools/ToolInitializer.java @@ -49,23 +49,7 @@ public ToolInitializer(Preferences preferences) public boolean isEimInstalled() { - if (!StringUtil.isEmpty(findEimOnSystemPath())) - { - return true; - } - - String eimExePathEnv = idfEnvironmentVariables.getEnvValue(IDFEnvironmentVariables.EIM_PATH); - boolean exists = !StringUtil.isEmpty(eimExePathEnv) && Files.exists(Paths.get(eimExePathEnv)); - if (!exists) - { - // Fallback: well-known install locations (e.g. user home .espressif/eim_gui, /Applications on macOS) - Path defaultEimPath = getDefaultEimPath(); - if (defaultEimPath != null) - { - exists = Files.exists(defaultEimPath); - } - } - return exists; + return !StringUtil.isEmpty(resolveEimExecutablePath(null)); } /** @@ -82,7 +66,8 @@ private String findEimOnSystemPath() /** * Resolves the EIM executable path: system {@code PATH} first, then {@code eimPath} from - * {@code eim_idf.json} when the path exists on disk, then {@link #getDefaultEimPath()}. + * {@code eim_idf.json} when the path exists on disk, then {@code EIM_PATH} env variable, then + * {@link #getDefaultEimPath()} (existence-checked). * * @param eimJson parsed JSON or {@code null} * @return resolved absolute path string, or empty if nothing could be resolved @@ -104,8 +89,19 @@ public String resolveEimExecutablePath(EimJson eimJson) } } + String eimExePathEnv = idfEnvironmentVariables.getEnvValue(IDFEnvironmentVariables.EIM_PATH); + if (!StringUtil.isEmpty(eimExePathEnv) && Files.exists(Paths.get(eimExePathEnv))) + { + return eimExePathEnv; + } + Path defaultEimPath = getDefaultEimPath(); - return defaultEimPath != null ? defaultEimPath.toString() : StringUtil.EMPTY; + if (defaultEimPath != null && Files.exists(defaultEimPath)) + { + return defaultEimPath.toString(); + } + + return StringUtil.EMPTY; } public boolean isEimIdfJsonPresent() @@ -208,17 +204,4 @@ else if (os.equals(Platform.OS_MACOSX)) return defaultEimPath; } - public void findAndSetEimPath() - { - String resolved = resolveEimExecutablePath(null); - if (!StringUtil.isEmpty(resolved)) - { - setEimPathInEnvVar(resolved); - } - } - - private void setEimPathInEnvVar(String eimPath) - { - idfEnvironmentVariables.addEnvVariable(IDFEnvironmentVariables.EIM_PATH, eimPath); - } } From fdcd485fc4861cfe3e91ef96d13a25a070869b2d Mon Sep 17 00:00:00 2001 From: Ali Azam Rana <85216275+alirana01@users.noreply.github.com> Date: Wed, 6 May 2026 14:04:53 +0200 Subject: [PATCH 3/3] fix for bug reported from Andrii --- .../idf/core/tools/ToolInitializer.java | 64 +++++++++++++------ 1 file changed, 44 insertions(+), 20 deletions(-) diff --git a/bundles/com.espressif.idf.core/src/com/espressif/idf/core/tools/ToolInitializer.java b/bundles/com.espressif.idf.core/src/com/espressif/idf/core/tools/ToolInitializer.java index 6a6f64531..3a9b90844 100644 --- a/bundles/com.espressif.idf.core/src/com/espressif/idf/core/tools/ToolInitializer.java +++ b/bundles/com.espressif.idf.core/src/com/espressif/idf/core/tools/ToolInitializer.java @@ -182,26 +182,50 @@ public boolean isEspIdfSet() public Path getDefaultEimPath() { String userHome = System.getProperty("user.home"); //$NON-NLS-1$ - Path defaultEimPath; - String os = Platform.getOS(); - if (os.equals(Platform.OS_WIN32)) - { - defaultEimPath = Paths.get(userHome, ".espressif", "eim_gui", //$NON-NLS-1$//$NON-NLS-2$ - "eim.exe"); //$NON-NLS-1$ - } - else if (os.equals(Platform.OS_MACOSX)) - { - defaultEimPath = Paths.get("/Applications", //$NON-NLS-1$ - "eim.app", "Contents", //$NON-NLS-1$//$NON-NLS-2$ - "MacOS", "eim"); //$NON-NLS-1$ //$NON-NLS-2$ - } - else - { - defaultEimPath = Paths.get(userHome, ".espressif", //$NON-NLS-1$ - "eim_gui", "eim"); //$NON-NLS-1$//$NON-NLS-2$ - } - - return defaultEimPath; + Path defaultEimPath; + String os = Platform.getOS(); + if (os.equals(Platform.OS_WIN32)) + { + defaultEimPath = Paths.get(userHome, ".espressif", "eim_gui", //$NON-NLS-1$//$NON-NLS-2$ + "eim.exe"); //$NON-NLS-1$ + if (!Files.exists(defaultEimPath)) + { + Path eimGuiDir = Paths.get(userHome, ".espressif", "eim_gui"); //$NON-NLS-1$ //$NON-NLS-2$ + if (Files.isDirectory(eimGuiDir)) + { + try (var entries = Files.list(eimGuiDir)) + { + Path found = entries + .filter(Files::isRegularFile) + .filter(p -> p.getFileName().toString().toLowerCase().startsWith("eim") //$NON-NLS-1$ + && p.getFileName().toString().toLowerCase().endsWith(".exe")) //$NON-NLS-1$ + .findFirst() + .orElse(null); + if (found != null) + { + return found; + } + } + catch (IOException e) + { + Logger.log(e); + } + } + } + } + else if (os.equals(Platform.OS_MACOSX)) + { + defaultEimPath = Paths.get("/Applications", //$NON-NLS-1$ + "eim.app", "Contents", //$NON-NLS-1$//$NON-NLS-2$ + "MacOS", "eim"); //$NON-NLS-1$ //$NON-NLS-2$ + } + else + { + defaultEimPath = Paths.get(userHome, ".espressif", //$NON-NLS-1$ + "eim_gui", "eim"); //$NON-NLS-1$//$NON-NLS-2$ + } + + return defaultEimPath; } }