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..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 @@ -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,16 +49,59 @@ public ToolInitializer(Preferences preferences) public boolean isEimInstalled() { + return !StringUtil.isEmpty(resolveEimExecutablePath(null)); + } + + /** + * 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 {@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 + */ + 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; + } + } + String eimExePathEnv = idfEnvironmentVariables.getEnvValue(IDFEnvironmentVariables.EIM_PATH); - boolean exists = !StringUtil.isEmpty(eimExePathEnv) && Files.exists(Paths.get(eimExePathEnv)); - if (!exists) + if (!StringUtil.isEmpty(eimExePathEnv) && Files.exists(Paths.get(eimExePathEnv))) + { + return eimExePathEnv; + } + + Path defaultEimPath = getDefaultEimPath(); + if (defaultEimPath != null && Files.exists(defaultEimPath)) { - // Fallback: check in user home .espressif/eim_gui folder - Path defaultEimPath = getDefaultEimPath(); - if (defaultEimPath != null) - exists = Files.exists(defaultEimPath); + return defaultEimPath.toString(); } - return exists; + + return StringUtil.EMPTY; } public boolean isEimIdfJsonPresent() @@ -138,38 +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; - } - - public void findAndSetEimPath() - { - Path defaultEimPath = getDefaultEimPath(); - - if (defaultEimPath != null) - setEimPathInEnvVar(defaultEimPath.toString()); + 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; } - private void setEimPathInEnvVar(String eimPath) - { - idfEnvironmentVariables.addEnvVariable(IDFEnvironmentVariables.EIM_PATH, 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: ");