-
Notifications
You must be signed in to change notification settings - Fork 133
IEP-1618: Generate Bug Report Feature #1298
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
b5d8352
af740f7
4f0658b
c55b406
381a532
98cfb66
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,230 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /******************************************************************************* | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * Copyright 2025 Espressif Systems (Shanghai) PTE LTD. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * All rights reserved. Use is subject to license terms. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| *******************************************************************************/ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| package com.espressif.idf.core.bug; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import java.io.File; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import java.io.IOException; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import java.lang.management.ManagementFactory; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import java.nio.file.Path; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import java.time.LocalDateTime; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import java.time.format.DateTimeFormatter; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import java.util.LinkedList; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import java.util.List; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import java.util.Locale; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import org.eclipse.core.resources.IWorkspace; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import org.eclipse.core.resources.ResourcesPlugin; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import org.eclipse.core.runtime.Platform; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import com.espressif.idf.core.logging.Logger; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import com.espressif.idf.core.util.FileUtil; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import com.espressif.idf.core.util.StringUtil; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * This class generates a bug report zip file containing: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * 1. Installed tools information | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * 2. Product information | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * 3. Basic system information (OS, Arch, Memory) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * 4. IDE metadata logs | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * 5. eim logs (if available) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * The generated zip file is named with a timestamp and stored in the workspace directory. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * @author Ali Azam Rana | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| public class BugReportGenerator | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private static final String bugReportDirectoryPrefix = "bug_report_"; //$NON-NLS-1$ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private String installedToolsCommandOutput; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private String productInformationCommandOutput; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private File bugReportDirectory; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private enum ByteUnit | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| B("B"), //$NON-NLS-1$ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| KB("KB"), //$NON-NLS-1$ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| MB("MB"), //$NON-NLS-1$ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| GB("GB"), //$NON-NLS-1$ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| TB("TB"), //$NON-NLS-1$ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| PB("PB"); //$NON-NLS-1$ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| final String label; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ByteUnit(String label) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| this.label = label; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ByteUnit next() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| int i = ordinal(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return i < PB.ordinal() ? values()[i + 1] : PB; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| public BugReportGenerator(String installedToolsCommandOutput, String productInformationCommandOutput) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| this.installedToolsCommandOutput = installedToolsCommandOutput; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| this.productInformationCommandOutput = productInformationCommandOutput; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd_HHmmss")); //$NON-NLS-1$ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| bugReportDirectory = getWorkspaceDirectory().resolve(bugReportDirectoryPrefix + timestamp + File.separator) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .toFile(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private File getEimLogPath() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| String eimPath = StringUtil.EMPTY; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| switch (Platform.getOS()) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| case Platform.OS_WIN32: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| eimPath = System.getenv("APPDATA"); //$NON-NLS-1$ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (!StringUtil.isEmpty(eimPath)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| eimPath = eimPath + "\\Local\\eim\\logs"; //$NON-NLS-1$ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| break; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
103
to
109
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Windows EIM logs path is incorrect. APPDATA points to Roaming; use LOCALAPPDATA. - case Platform.OS_WIN32:
- eimPath = System.getenv("APPDATA"); //$NON-NLS-1$
+ case Platform.OS_WIN32:
+ eimPath = System.getenv("LOCALAPPDATA"); //$NON-NLS-1$
if (!StringUtil.isEmpty(eimPath))
{
eimPath = eimPath + "\\Local\\eim\\logs"; //$NON-NLS-1$
}Also consider simply: LOCALAPPDATA + "\eim\logs". 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| case Platform.OS_MACOSX: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| eimPath = System.getProperty("user.home"); //$NON-NLS-1$ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (!StringUtil.isEmpty(eimPath)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| eimPath = eimPath + "/Library/Application Support/eim/logs"; //$NON-NLS-1$ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| break; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| case Platform.OS_LINUX: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| eimPath = System.getProperty("user.home"); //$NON-NLS-1$ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (!StringUtil.isEmpty(eimPath)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| eimPath = eimPath + "/.local/share/.eim/logs"; //$NON-NLS-1$ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| break; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| default: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| break; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return new File(eimPath); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+128
to
+129
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Prevent catastrophic copy when EIM path is missing. getEimLogPath() returns new File("") on empty, which resolves to the CWD; copyDirectory would then copy the whole working dir. Return null when unresolved and guard the copy. - return new File(eimPath);
+ if (StringUtil.isEmpty(eimPath)) {
+ return null;
+ }
+ return new File(eimPath);- File eimLogPath = getEimLogPath();
- File eimLogDir = new File(bugReportDirectory.getAbsolutePath() + File.separator + "eim_logs"); //$NON-NLS-1$ )
- FileUtil.copyDirectory(eimLogPath, eimLogDir);
+ File eimLogPath = getEimLogPath();
+ if (eimLogPath != null && eimLogPath.exists() && eimLogPath.isDirectory()) {
+ File eimLogDir = new File(bugReportDirectory, "eim_logs"); //$NON-NLS-1$
+ FileUtil.copyDirectory(eimLogPath, eimLogDir);
+ }Also applies to: 279-282 🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private Path getWorkspaceDirectory() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| IWorkspace workspace = ResourcesPlugin.getWorkspace(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| File workspaceRoot = workspace.getRoot().getLocation().toFile(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return workspaceRoot.toPath(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private File getIdeMetadataLogsFile() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| File metadataDir = getWorkspaceDirectory().resolve(".metadata").toFile(); //$NON-NLS-1$ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return metadataDir; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private File createBasicSystemInfoFile() throws IOException | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| String osName = System.getProperty("os.name", "Unknown"); //$NON-NLS-1$ //$NON-NLS-2$ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| String osVersion = System.getProperty("os.version", "Unknown"); //$NON-NLS-1$ //$NON-NLS-2$ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| String arch = System.getProperty("os.arch", "Unknown"); //$NON-NLS-1$//$NON-NLS-2$ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| long freePhys = -1L; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| long totalPhys = -1L; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| try | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| com.sun.management.OperatingSystemMXBean osBean = (com.sun.management.OperatingSystemMXBean) ManagementFactory | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .getOperatingSystemMXBean(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| freePhys = osBean.getFreeMemorySize(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| totalPhys = osBean.getTotalMemorySize(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+204
to
+208
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Compile error: wrong com.sun.management.OperatingSystemMXBean methods. Use getFreePhysicalMemorySize()/getTotalPhysicalMemorySize(). - freePhys = osBean.getFreeMemorySize();
- totalPhys = osBean.getTotalMemorySize();
+ freePhys = osBean.getFreePhysicalMemorySize();
+ totalPhys = osBean.getTotalPhysicalMemorySize();🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| catch (Throwable t) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // jdk.management module not present or different VM; leave values as -1. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| StringBuilder sb = new StringBuilder(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| sb.append("Basic System Info").append(System.lineSeparator()); //$NON-NLS-1$ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| sb.append("==================").append(System.lineSeparator()); //$NON-NLS-1$ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| sb.append("Generated: ").append(LocalDateTime.now()).append(System.lineSeparator()); //$NON-NLS-1$ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| sb.append("OS : ").append(osName).append(" ").append(osVersion).append(System.lineSeparator()); //$NON-NLS-1$ //$NON-NLS-2$ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| sb.append("Arch : ").append(arch).append(System.lineSeparator()); //$NON-NLS-1$ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (totalPhys >= 0 && freePhys >= 0) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| long used = totalPhys - freePhys; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| sb.append("Memory :").append(System.lineSeparator()); //$NON-NLS-1$ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| sb.append(" Total : ").append(humanBytes(totalPhys)).append(" (").append(totalPhys) //$NON-NLS-1$ //$NON-NLS-2$ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .append(" bytes)").append(System.lineSeparator()); //$NON-NLS-1$ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| sb.append(" Available : ").append(humanBytes(freePhys)).append(" (").append(freePhys).append(" bytes)") //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .append(System.lineSeparator()); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| sb.append(" In Use : ").append(humanBytes(used)).append(" (").append(used).append(" bytes)") //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .append(System.lineSeparator()); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| else | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| sb.append("Memory : Unavailable (OS-level physical memory query unsupported on this JVM)") //$NON-NLS-1$ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .append(System.lineSeparator()); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Use your existing helper that writes content to a temp file with the given name. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // This will create a file named exactly "basic_system_info". | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return FileUtil.createFileWithContentsInDirectory("basic_system_info", sb.toString(), //$NON-NLS-1$ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| bugReportDirectory.getAbsolutePath()); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private static String humanBytes(long bytes) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| double v = (double) bytes; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ByteUnit unit = ByteUnit.B; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| while (v >= 1024.0 && unit != ByteUnit.PB) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| v /= 1024.0; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| unit = unit.next(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return String.format(Locale.ROOT, "%.2f %s", v, unit.label); //$NON-NLS-1$ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * Generates a bug report zip and also returns the path of the generated zip file. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * @return | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| public String generateBugReport() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (!bugReportDirectory.exists()) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| bugReportDirectory.mkdirs(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| try | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| File installedToolsFile = FileUtil.createFileWithContentsInDirectory("installed_tools.txt", //$NON-NLS-1$ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| installedToolsCommandOutput, bugReportDirectory.getAbsolutePath()); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| File productInfoFile = FileUtil.createFileWithContentsInDirectory("product_information.txt", //$NON-NLS-1$ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| productInformationCommandOutput, bugReportDirectory.getAbsolutePath()); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| File basicSysInfoFile = createBasicSystemInfoFile(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
267
to
271
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Null-safe file writes for command outputs. Avoid NPE if either output is null. - File installedToolsFile = FileUtil.createFileWithContentsInDirectory("installed_tools.txt", //$NON-NLS-1$
- installedToolsCommandOutput, bugReportDirectory.getAbsolutePath());
- File productInfoFile = FileUtil.createFileWithContentsInDirectory("product_information.txt", //$NON-NLS-1$
- productInformationCommandOutput, bugReportDirectory.getAbsolutePath());
+ String installedToolsOut = installedToolsCommandOutput == null ? StringUtil.EMPTY : installedToolsCommandOutput;
+ String productInfoOut = productInformationCommandOutput == null ? StringUtil.EMPTY : productInformationCommandOutput;
+ File installedToolsFile = FileUtil.createFileWithContentsInDirectory("installed_tools.txt", //$NON-NLS-1$
+ installedToolsOut, bugReportDirectory.getAbsolutePath());
+ File productInfoFile = FileUtil.createFileWithContentsInDirectory("product_information.txt", //$NON-NLS-1$
+ productInfoOut, bugReportDirectory.getAbsolutePath());📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| List<File> filesToZip = new LinkedList<>(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| filesToZip.add(installedToolsFile); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| filesToZip.add(productInfoFile); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| filesToZip.add(basicSysInfoFile); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| File metadataLogsFile = getIdeMetadataLogsFile(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| File ideLogDir = new File(bugReportDirectory.getAbsolutePath() + File.separator + "ide_metadata_logs"); //$NON-NLS-1$ ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fix stray There’s an extra closing parenthesis after the - File ideLogDir = new File(bugReportDirectory.getAbsolutePath() + File.separator + "ide_metadata_logs"); //$NON-NLS-1$ )
+ File ideLogDir = new File(bugReportDirectory.getAbsolutePath() + File.separator + "ide_metadata_logs"); //$NON-NLS-1$- File eimLogDir = new File(bugReportDirectory.getAbsolutePath() + File.separator + "eim_logs"); //$NON-NLS-1$ )
+ File eimLogDir = new File(bugReportDirectory.getAbsolutePath() + File.separator + "eim_logs"); //$NON-NLS-1$Also applies to: 292-292 🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (!ideLogDir.exists()) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ideLogDir.mkdirs(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| FileUtil.copyDirectory(metadataLogsFile, ideLogDir); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| File metadataLogsFile = getIdeMetadataLogsFile(); | |
| File ideLogDir = new File(bugReportDirectory.getAbsolutePath() + File.separator + "ide_metadata_logs"); //$NON-NLS-1$ ) | |
| if (!ideLogDir.exists()) | |
| { | |
| ideLogDir.mkdirs(); | |
| } | |
| FileUtil.copyDirectory(metadataLogsFile, ideLogDir); | |
| File ideLogDir = new File(bugReportDirectory.getAbsolutePath() + File.separator + "ide_metadata_logs"); //$NON-NLS-1$ | |
| if (!ideLogDir.exists()) { | |
| ideLogDir.mkdirs(); | |
| } | |
| // Copy only the workspace .log file to reduce PII exposure | |
| File workspaceMeta = getIdeMetadataLogsFile(); | |
| File workspaceLog = new File(workspaceMeta, ".log"); //$NON-NLS-1$ | |
| if (workspaceLog.exists()) { | |
| java.nio.file.Files.copy( | |
| workspaceLog.toPath(), | |
| new File(ideLogDir, "workspace.log").toPath(), | |
| java.nio.file.StandardCopyOption.REPLACE_EXISTING); | |
| } |
🤖 Prompt for AI Agents
In
bundles/com.espressif.idf.core/src/com/espressif/idf/core/bug/BugReportGenerator.java
around lines 208-216, the code currently copies the entire workspace .metadata
which may include PII; instead, restrict what is copied by whitelisting only
specific log files/subfolders (e.g., .metadata/.log and any approved subfolders)
or by copying a curated list of filenames. Change the logic to create the
ide_metadata_logs directory, then iterate a small whitelist (or patterns like
"*.log") and copy each allowed file/subfolder individually (using
FileUtil.copyFile/FileUtil.copyDirectory per item), and add null/exists checks
and clear comments documenting the whitelist; do not copy the whole metadata
directory.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Guard optional EIM logs copy.
Skip copy when source doesn’t exist to avoid noisy errors.
- File eimLogPath = getEimLogPath();
- File eimLogDir = new File(bugReportDirectory.getAbsolutePath() + File.separator + "eim_logs"); //$NON-NLS-1$ )
- FileUtil.copyDirectory(eimLogPath, eimLogDir);
+ File eimLogPath = getEimLogPath();
+ if (eimLogPath.exists()) {
+ File eimLogDir = new File(bugReportDirectory.getAbsolutePath() + File.separator + "eim_logs"); //$NON-NLS-1$
+ FileUtil.copyDirectory(eimLogPath, eimLogDir);
+ }📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| File eimLogPath = getEimLogPath(); | |
| File eimLogDir = new File(bugReportDirectory.getAbsolutePath() + File.separator + "eim_logs"); //$NON-NLS-1$ ) | |
| FileUtil.copyDirectory(eimLogPath, eimLogDir); | |
| File eimLogPath = getEimLogPath(); | |
| if (eimLogPath.exists()) { | |
| File eimLogDir = new File(bugReportDirectory.getAbsolutePath() + File.separator + "eim_logs"); //$NON-NLS-1$ | |
| FileUtil.copyDirectory(eimLogPath, eimLogDir); | |
| } |
🤖 Prompt for AI Agents
In
bundles/com.espressif.idf.core/src/com/espressif/idf/core/bug/BugReportGenerator.java
around lines 217 to 220, the code unconditionally attempts to copy EIM logs
which may not exist; update it to guard the copy by checking that
getEimLogPath() returned a non-null File that exists (and is a directory/file as
appropriate) before calling FileUtil.copyDirectory, and if the source does not
exist simply skip the copy (optionally log a debug/info message) to avoid noisy
errors.
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,34 @@ | ||||||||||||||||||||||||||||||||||||||||||||
| /******************************************************************************* | ||||||||||||||||||||||||||||||||||||||||||||
| * Copyright 2025 Espressif Systems (Shanghai) PTE LTD. | ||||||||||||||||||||||||||||||||||||||||||||
| * All rights reserved. Use is subject to license terms. | ||||||||||||||||||||||||||||||||||||||||||||
| *******************************************************************************/ | ||||||||||||||||||||||||||||||||||||||||||||
| package com.espressif.idf.core.bug; | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| import java.awt.Desktop; | ||||||||||||||||||||||||||||||||||||||||||||
| import java.io.UnsupportedEncodingException; | ||||||||||||||||||||||||||||||||||||||||||||
| import java.net.URI; | ||||||||||||||||||||||||||||||||||||||||||||
| import java.net.URLEncoder; | ||||||||||||||||||||||||||||||||||||||||||||
| import java.nio.charset.StandardCharsets; | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||||||||||||||||
| * Opens the default web browser to create a new issue on the GitHub repository. | ||||||||||||||||||||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||||||||||||||||||||
| * @author Ali Azam Rana | ||||||||||||||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||||||||||||
| public class GithubIssueOpener | ||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||
| private static final String issueUrlBase = "https://github.com/espressif/idf-eclipse-plugin/issues/new"; //$NON-NLS-1$ | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| public static void openNewIssue() | ||||||||||||||||||||||||||||||||||||||||||||
| throws Exception | ||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||
| String q = "&template=" + enc("bug_report.md"); // e.g. "bug_report.md" //$NON-NLS-1$ //$NON-NLS-2$ | ||||||||||||||||||||||||||||||||||||||||||||
| URI uri = new URI(issueUrlBase + "?" + q); //$NON-NLS-1$ | ||||||||||||||||||||||||||||||||||||||||||||
| Desktop.getDesktop().browse(uri); | ||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+20
to
+28
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Guard Desktop.browse for headless/unsupported environments. Avoid throwing on systems without a desktop or browse action. - Desktop.getDesktop().browse(uri);
+ if (!Desktop.isDesktopSupported() || !Desktop.getDesktop().isSupported(Desktop.Action.BROWSE)) {
+ throw new IllegalStateException("Desktop browse is not supported on this system"); //$NON-NLS-1$
+ }
+ Desktop.getDesktop().browse(uri);📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| private static String enc(String s) throws UnsupportedEncodingException | ||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||
| return URLEncoder.encode(s, StandardCharsets.UTF_8.toString()); | ||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: the naming convention for a final static field is all uppercase letters with underscores separating words.