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;
}
}