Skip to content

Add customOpenOCDPath setting for custom openOCD to use in extension.#1829

Merged
brianignacio5 merged 4 commits into
masterfrom
feature/custom-openocd
May 27, 2026
Merged

Add customOpenOCDPath setting for custom openOCD to use in extension.#1829
brianignacio5 merged 4 commits into
masterfrom
feature/custom-openocd

Conversation

@brianignacio5

@brianignacio5 brianignacio5 commented Apr 28, 2026

Copy link
Copy Markdown
Collaborator

Description

This pull request adds support for specifying a custom OpenOCD executable path in the ESP-IDF VS Code extension. Users can now configure the absolute path to their preferred OpenOCD binary via the new idf.customOpenOCDPath setting. If this setting is unset or invalid, the extension will fall back to searching for OpenOCD in the system PATH. The change is thoroughly documented and integrated into the extension's configuration, environment preparation, and reporting features.

The most important changes include:

Feature: Custom OpenOCD Path Support

  • Added a new idf.customOpenOCDPath configuration option to package.json, with localization support in all relevant package.nls.*.json files. This option allows users to specify an absolute path to a custom OpenOCD executable. [1] [2] [3] [4] [5] [6]
  • Implemented logic in OpenOCDManager.getOpenOcdPath() to use the custom path if set and valid, otherwise fallback to searching in PATH. Updated all usages of OpenOCD path resolution to use this method. [1] [2] [3] [4] [5] [6] [7] [8] [9] [10]

Documentation Updates

  • Added documentation for the new setting in both English and Chinese debug setup guides (debugproject.rst), and updated the settings reference in both languages. [1] [2] [3] [4]

Reporting and Diagnostics

  • Extended the extension's configuration reporting and diagnostics to include the new customOpenOcdPath setting, its access status, and its value in generated reports. [1] [2] [3] [4] [5] [6] [7] [8]

These changes improve flexibility for users who need to use a custom or patched version of OpenOCD, and ensure the new option is well-documented and visible in diagnostics.

Fixes #1799

Type of change

  • New feature (non-breaking change which adds functionality)

Steps to test this pull request

  1. Define idf.customOpenOcdPath to OpenOCD from a different location from the current ESP-IDF setup.
  2. Execute ESP-IDF: OpenOCD Manager command to start OpenOCD or from the status bar [OpenOCD] button.
  3. Observe results. The OpenOCD used is from the idf.customOpenOcdPath and the ESP-IDF: Doctor Command shows the custom OpenOCD path and if the file is accessible.
  • Expected behaviour:

The OpenOCD used is from the idf.customOpenOcdPath otherwise it will use OpenOCD from ESP-IDF setup.

  • Expected output:
    The OpenOCD used is from the idf.customOpenOcdPath otherwise it will use OpenOCD from ESP-IDF setup.

How has this been tested?

Manual testing by following steps above.

Test Configuration:

  • ESP-IDF Version: 6.0.0
  • OS (Windows,Linux and macOS): macOS

Dependent components impacted by this PR:

  • Component 1
  • Component 2

Checklist

  • PR Self Reviewed
  • Applied Code formatting
  • Added Documentation
  • Added Unit Test
  • Verified on all platforms - Windows,Linux and macOS

Summary by CodeRabbit

  • New Features

    • Configure a custom OpenOCD executable via the idf.customOpenOCDPath VS Code setting; empty/invalid values fall back to locating OpenOCD on your system PATH.
  • Improvements

    • Added validation for the configured OpenOCD path and unified, more reliable OpenOCD resolution and fallback behavior.
  • Documentation

    • New user guide and settings docs (English and Chinese) with an example configuration snippet.
  • Localization

    • UI text for the new setting added in multiple languages.
  • Diagnostics

    • Troubleshooting report now includes the custom OpenOCD path and its access status.

@brianignacio5 brianignacio5 self-assigned this Apr 28, 2026
@brianignacio5 brianignacio5 added the Feature A new feature label Apr 28, 2026
@coderabbitai

coderabbitai Bot commented Apr 28, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

Adds a resource-scoped idf.customOpenOCDPath setting and centralizes OpenOCD binary resolution in OpenOCDManager.getOpenOcdPath(), which validates a configured absolute executable path and otherwise falls back to searching openocd (and openocd-esp32) on the system PATH. Documentation and i18n updated.

Changes

Cohort / File(s) Summary
Documentation
docs_espressif/en/debugproject.rst, docs_espressif/zh_CN/debugproject.rst
New guide text showing how to set idf.customOpenOCDPath in .vscode/settings.json, example snippet, and fallback-to-PATH behavior.
Settings Documentation
docs_espressif/en/settings.rst, docs_espressif/zh_CN/settings.rst
Added descriptive entry for idf.customOpenOCDPath explaining it accepts an absolute OpenOCD executable path and falls back to PATH when empty/invalid.
Extension Configuration & Locales
package.json, package.nls.json, package.nls.es.json, package.nls.pt.json, package.nls.ru.json, package.nls.zh-cn.json
Declared new resource-scoped config idf.customOpenOCDPath and added localized description keys (param.customOpenOCDPath).
OpenOCD Resolution & Usage
src/espIdf/openOcd/openOcdManager.ts, src/common/prepareEnv.ts, src/espIdf/hints/utils.ts, src/espIdf/setTarget/DevkitsCommand.ts, src/espIdf/setTarget/index.ts
Added OpenOCDManager.getOpenOcdPath() to prefer validated idf.customOpenOCDPath and fall back to PATH; callers refactored to use this central resolver and adjust script/path resolution accordingly.
Configuration Surface & Validation
src/support/configurationSettings.ts, src/support/configurationAccess.ts, src/support/types.ts, src/support/initReportObj.ts, src/support/writeReport.ts
Added customOpenOcdPath to configuration types, access validation (filesystem execute check), report initialization, and reporting output.
Logging
src/extension.ts
Minor reformat of a Logger.info message in ensureEimAndLaunch to multi-line template.

Sequence Diagram(s)

sequenceDiagram
  participant VSCode as "VS Code Extension"
  participant Config as "Workspace Settings\n(idf.customOpenOCDPath)"
  participant OpenOCDMgr as "OpenOCDManager"
  participant FS as "Filesystem (exists & exec)"
  participant PATH as "PATH resolver"
  participant Consumer as "Caller (prepareEnv / devkits / hints)"

  VSCode->>Config: read `idf.customOpenOCDPath`
  Config-->>OpenOCDMgr: provide configured path (may be empty)
  OpenOCDMgr->>FS: check exists & executable (trimmed path)
  alt configured path valid
    FS-->>OpenOCDMgr: exists & executable
    OpenOCDMgr-->>Consumer: return configured absolute path
  else configured path empty/invalid
    FS-->>OpenOCDMgr: not valid
    OpenOCDMgr->>PATH: search for `openocd` / `openocd-esp32`
    PATH-->>OpenOCDMgr: resolved path or null
    OpenOCDMgr-->>Consumer: return PATH-resolved path or null
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • radurentea
  • AndriiFilippov

Poem

🐰 I sniffed the paths and took a hop,

Found a custom OpenOCD on the top,
If your path is tidy, I’ll use it fast,
If it’s not, PATH will help at last,
Hoppy debugging — build and hop!

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Out of Scope Changes check ❓ Inconclusive Minor formatting change in src/extension.ts appears unrelated to customOpenOCDPath feature. Multi-line template formatting adjustment to Logger.info message in ensureEimAndLaunch seems outside the scope of the feature. Clarify the purpose of the multi-line template formatting change in src/extension.ts or consider moving it to a separate PR.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: adding a customOpenOCDPath setting for custom OpenOCD usage in the extension.
Linked Issues check ✅ Passed All coding requirements from issue #1799 are met: the PR implements a customOpenOCDPath configuration setting, modifies OpenOCD path resolution to prefer the custom path, and updates all path resolution calls throughout the codebase.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/custom-openocd

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces the idf.customOpenOCDPath configuration setting, allowing users to specify a custom OpenOCD executable. The changes span documentation, localization files, and the core logic for resolving the OpenOCD path across multiple modules, including the troubleshooting report generator. Review feedback suggests improving the implementation in OpenOCDManager by using asynchronous file existence checks instead of synchronous ones to maintain consistency with the rest of the codebase. Additionally, a minor wording adjustment was recommended for the support report output to ensure consistent labeling of configuration access entries.

Comment thread src/espIdf/openOcd/openOcdManager.ts Outdated
Comment thread src/espIdf/openOcd/openOcdManager.ts Outdated
Comment thread src/support/writeReport.ts Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/espIdf/setTarget/DevkitsCommand.ts (1)

60-69: ⚠️ Potential issue | 🟠 Major

Reuse the checked helper-script lookup for custom installs.

getOpenOcdPath() now accepts arbitrary binaries, but this code still assumes share/openocd/espressif/tools/esp_detect_config.py lives two directories above the binary. That only holds for the bundled layout, so a valid custom install can now fail later with a missing script. Please reuse getScriptPath() here or validate scriptPath before launching Python.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/espIdf/setTarget/DevkitsCommand.ts` around lines 60 - 69, The code in
DevkitsCommand.ts constructs scriptPath relative to the openOcd binary which
only works for the bundled layout; instead use the existing helper
getScriptPath(openOcdPath, "esp_detect_config.py") (or call getScriptPath() with
the binary path) so custom installs are supported, or if you prefer keep your
own resolution then validate that scriptPath exists before spawning Python and
surface a clear error if missing; update references to scriptPath and the call
site that launches esp_detect_config.py to use the validated path returned by
getScriptPath().
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@docs_espressif/en/debugproject.rst`:
- Around line 95-96: The heading "Using a Custom OpenOCD Path" has an underline
that is shorter than the title; update the underline so it matches the exact
length of the title (use the same character used for other headings, e.g., '-'
repeated to match the title length) so Sphinx stops warning and the docs build
succeeds.

In `@src/espIdf/openOcd/openOcdManager.ts`:
- Around line 53-62: The code currently returns customOpenOcdPath after
existsSync; update getOpenOcdPath so that after reading idf.customOpenOCDPath
and trimming, you verify the path is a file and executable before returning it:
use fs.statSync or fs.lstatSync (ensure .isFile()) and fs.accessSync(path,
fs.constants.X_OK) (or async equivalents) to confirm executability, and if
either check fails, fall through to the existing isBinInPath("openocd",
modifiedEnv, ["openocd-esp32"]) call; reference the customOpenOcdPath variable,
the idfConf.readParameter call that retrieves it, and the isBinInPath helper to
locate where to add these checks.

In `@src/support/configurationAccess.ts`:
- Around line 62-68: The check is using read permission (constants.R_OK) for an
executable path; change the permission flag passed to canAccessFile so it checks
execute permission instead (use constants.X_OK) when setting
reportedResult.configurationAccess.customOpenOcdPath based on
reportedResult.configurationSettings.customOpenOcdPath; update the call site in
configurationAccess.ts (the canAccessFile invocation) to pass the execute
constant and ensure the constants symbol X_OK is available.

In `@src/support/configurationSettings.ts`:
- Line 69: The config lookup uses the wrong casing for the key: change the
conf.get call that populates customOpenOcdPath (in configurationSettings.ts) to
use "idf.customOpenOCDPath" (capital D) so it matches the package.json
contribution id; update the property access in the object initializer that
currently reads customOpenOcdPath: conf.get("idf.customOpenOcdPath") to
conf.get("idf.customOpenOCDPath") so the setting is actually populated for
reports/diagnostics.

In `@src/support/writeReport.ts`:
- Around line 75-77: The report lines that reference
reportedResult.configurationSettings.customOpenOcdPath should be corrected to
use the proper setting name casing and distinct label text: replace occurrences
that print "idf.customOpenOcdPath" with "idf.customOpenOCDPath" and make the
access/secondary row use a clearer label (e.g., "Configured OpenOCD path
(idf.customOpenOCDPath)" for the settings line and a distinct label like
"OpenOCD executable path detected" for the access/usage line); update both
instances around reportedResult.configurationSettings.customOpenOcdPath
(including the similar block at lines ~98-100) so the label text and casing are
consistent and not duplicated.

---

Outside diff comments:
In `@src/espIdf/setTarget/DevkitsCommand.ts`:
- Around line 60-69: The code in DevkitsCommand.ts constructs scriptPath
relative to the openOcd binary which only works for the bundled layout; instead
use the existing helper getScriptPath(openOcdPath, "esp_detect_config.py") (or
call getScriptPath() with the binary path) so custom installs are supported, or
if you prefer keep your own resolution then validate that scriptPath exists
before spawning Python and surface a clear error if missing; update references
to scriptPath and the call site that launches esp_detect_config.py to use the
validated path returned by getScriptPath().
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 23c7bd7a-df0d-4006-a624-623928122636

📥 Commits

Reviewing files that changed from the base of the PR and between dc20bd4 and f2d8314.

📒 Files selected for processing (20)
  • docs_espressif/en/debugproject.rst
  • docs_espressif/en/settings.rst
  • docs_espressif/zh_CN/debugproject.rst
  • docs_espressif/zh_CN/settings.rst
  • package.json
  • package.nls.es.json
  • package.nls.json
  • package.nls.pt.json
  • package.nls.ru.json
  • package.nls.zh-cn.json
  • src/common/prepareEnv.ts
  • src/espIdf/hints/utils.ts
  • src/espIdf/openOcd/openOcdManager.ts
  • src/espIdf/setTarget/DevkitsCommand.ts
  • src/extension.ts
  • src/support/configurationAccess.ts
  • src/support/configurationSettings.ts
  • src/support/initReportObj.ts
  • src/support/types.ts
  • src/support/writeReport.ts

Comment thread docs_espressif/en/debugproject.rst
Comment thread src/espIdf/openOcd/openOcdManager.ts Outdated
Comment thread src/support/configurationAccess.ts
Comment thread src/support/configurationSettings.ts Outdated
Comment thread src/support/writeReport.ts
@github-actions

github-actions Bot commented Apr 28, 2026

Copy link
Copy Markdown

Download the artifacts for this pull request:
You can test these changes by installing this VSIX by click menu View -> Command Palette..., type Install from VSIX and then select downloaded esp-idf-extension.vsix file to install the extension.

Co-authored-by: Copilot <copilot@github.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
src/espIdf/setTarget/DevkitsCommand.ts (1)

136-156: Prefer Logger.error for caught exceptions.

Logger.errorNotify(...) changes the catch-path behavior and diverges from the project guideline for caught errors. Keep the logging call on Logger.error(...) and leave notification handling separate if you still want the user-facing message.

As per coding guidelines: Use Logger.error(message, error, "scope identifier") for caught errors, with a consistent scope identifier as the third argument.

♻️ Suggested adjustment
-            Logger.errorNotify(msg, error as Error, "DevkitsCommand");
+            Logger.error(msg, error as Error, "DevkitsCommand");
             OutputChannel.appendLine(msg, "ESP Detect Config");
             OutputChannel.show();
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/espIdf/setTarget/DevkitsCommand.ts` around lines 136 - 156, The catch
handlers in DevkitsCommand are using Logger.errorNotify(...) for caught
exceptions which breaks the project guideline; change those calls to
Logger.error(msg, error as Error, "DevkitsCommand") in both the inner catch
inside the async callback and the outer catch (including the opts?.silent branch
where currently Logger.error(...) is used for silent true but Logger.errorNotify
is used for non-silent), ensuring all caught-error logging uses Logger.error
with the same scope identifier "DevkitsCommand" and keep notification behavior
separate if needed.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/espIdf/openOcd/openOcdManager.ts`:
- Around line 53-75: getOpenOcdPath currently uses lstatSync(...).isFile() which
rejects symlinks; replace that call with statSync(...).isFile() so the function
follows symlinks to real executables, keeping the existing
accessSync(customOpenOcdPath, constants.X_OK) check and try/catch behavior;
update the reference in getOpenOcdPath (replace lstatSync with statSync) and
ensure the rest of the logic (returning customOpenOcdPath or falling back to
isBinInPath) remains unchanged.

In `@src/espIdf/setTarget/DevkitsCommand.ts`:
- Around line 50-60: Remove the guard that throws when openOCDVersion is falsy
and instead call getScriptPath using the resolved OpenOCD binary location
regardless of whether parsing produced a version string; keep openOCDVersion
only for informational logging. Concretely, stop throwing in the openOCDVersion
check, call this.getScriptPath(...) even when openOCDVersion is empty (pass the
binary path the method expects), and only use openOCDVersion for
logs/diagnostics. Apply the same change to the second occurrence that mirrors
this logic (the block referenced at 162-172) so both code paths perform script
discovery based on the binary location and not on the parsed version value.

---

Nitpick comments:
In `@src/espIdf/setTarget/DevkitsCommand.ts`:
- Around line 136-156: The catch handlers in DevkitsCommand are using
Logger.errorNotify(...) for caught exceptions which breaks the project
guideline; change those calls to Logger.error(msg, error as Error,
"DevkitsCommand") in both the inner catch inside the async callback and the
outer catch (including the opts?.silent branch where currently Logger.error(...)
is used for silent true but Logger.errorNotify is used for non-silent), ensuring
all caught-error logging uses Logger.error with the same scope identifier
"DevkitsCommand" and keep notification behavior separate if needed.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e7bd02a5-8684-43a5-9c35-1ba7da06d30b

📥 Commits

Reviewing files that changed from the base of the PR and between 1ac7ae9 and 8c7b991.

📒 Files selected for processing (5)
  • src/espIdf/openOcd/openOcdManager.ts
  • src/espIdf/setTarget/DevkitsCommand.ts
  • src/support/configurationAccess.ts
  • src/support/configurationSettings.ts
  • src/support/writeReport.ts
✅ Files skipped from review due to trivial changes (2)
  • src/support/configurationSettings.ts
  • src/support/writeReport.ts

Comment thread src/espIdf/openOcd/openOcdManager.ts
Comment thread src/espIdf/setTarget/DevkitsCommand.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
src/espIdf/setTarget/index.ts (1)

105-116: Avoid resolving OpenOCD twice on the target-selection path.

runDevkitsScript() now owns the getOpenOcdPath() / getScriptPath() lookup, so this preflight check only adds another openocd --version probe and can drift from the actual execution path if the config changes mid-flow.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/espIdf/setTarget/index.ts` around lines 105 - 116, Remove the redundant
preflight OpenOCD probing: do not call OpenOCDManager.init()/version(),
OpenOCDManager.getOpenOcdPath(...) or devkitsCmd.getScriptPath(...) before
running the script because runDevkitsScript() now performs those lookups itself;
instead, simply create the DevkitsCommand (new
DevkitsCommand(workspaceFolder.uri)), optionally configure env via
configureEnvVariables(...) if needed, then call devkitsCmd.runDevkitsScript(...)
directly and use its result. Update any code that relied on the earlier openOCD
variables (openOCDVersion, openOcdPath, scriptPath) to use the output/status
returned by runDevkitsScript() or let runDevkitsScript handle reporting.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/espIdf/setTarget/index.ts`:
- Around line 105-116: Remove the redundant preflight OpenOCD probing: do not
call OpenOCDManager.init()/version(), OpenOCDManager.getOpenOcdPath(...) or
devkitsCmd.getScriptPath(...) before running the script because
runDevkitsScript() now performs those lookups itself; instead, simply create the
DevkitsCommand (new DevkitsCommand(workspaceFolder.uri)), optionally configure
env via configureEnvVariables(...) if needed, then call
devkitsCmd.runDevkitsScript(...) directly and use its result. Update any code
that relied on the earlier openOCD variables (openOCDVersion, openOcdPath,
scriptPath) to use the output/status returned by runDevkitsScript() or let
runDevkitsScript handle reporting.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: d17cf060-9d17-40e4-81bf-8147b72290c3

📥 Commits

Reviewing files that changed from the base of the PR and between 8c7b991 and b84e9ce.

📒 Files selected for processing (3)
  • src/espIdf/openOcd/openOcdManager.ts
  • src/espIdf/setTarget/DevkitsCommand.ts
  • src/espIdf/setTarget/index.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/espIdf/openOcd/openOcdManager.ts

@kolipakakondal kolipakakondal added this to the v2.2.0 milestone Apr 30, 2026
@AndriiFilippov

Copy link
Copy Markdown
Collaborator

@brianignacio5 hi !

Tested under:
OS: Windows 11 / Mac arm64

Custom OpenOCD path works ✅
Fallback if custom path is invalid ✅
Doctor command report contains info Access to Custom OpenOCD path (idf.customOpenOCDPath) true / false

LGTM 👍

@brianignacio5 brianignacio5 merged commit 7cbde5c into master May 27, 2026
5 checks passed
@brianignacio5 brianignacio5 deleted the feature/custom-openocd branch May 27, 2026 00:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Feature A new feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature Request]: Use custom openocd build

3 participants