Skip to content

feat: support ${workspaceFolder} and relative paths in cmake.exclude#4689

Draft
Copilot wants to merge 8 commits intomainfrom
copilot/add-cmake-exclude-path-support
Draft

feat: support ${workspaceFolder} and relative paths in cmake.exclude#4689
Copilot wants to merge 8 commits intomainfrom
copilot/add-cmake-exclude-path-support

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Feb 3, 2026

This changes visible behavior

The following changes are proposed:

  • Add expandExcludePath() and expandExcludePaths() functions in util.ts to expand path variables and resolve relative paths
  • Update projectController.ts to expand exclude paths before comparison in addFolder() and doExcludedFoldersChange()
  • Add unit tests for path expansion functionality with comprehensive documentation
  • Update docs/cmake-settings.md to mark cmake.exclude as supporting substitution
  • Update CHANGELOG.md with feature description and PR link

The purpose of this change

cmake.exclude only accepted absolute paths. Variable paths (${workspaceFolder}, ${workspaceFolder:Name}) and relative paths were not resolved, preventing portable workspace configurations.

Now supports:

{
  "cmake.exclude": [
    "${workspaceFolder}/subproject",
    "${workspaceFolder:OtherRoot}",
    "relative/path"
  ]
}

Path expansion behavior:

  • ${workspaceFolder} → current workspace folder path
  • ${workspaceFolder:Name} → named workspace folder path (case-insensitive lookup)
  • Relative paths → resolved against workspace folder
  • Unresolved variables (folder not found) → left as-is, treated as relative path

Other Notes/Information

The ${workspaceFolder:Name} lookup is case-insensitive, consistent with VS Code's behavior on Windows/macOS file systems.

Test Updates Documentation

Added comprehensive unit tests in test/unit-tests/util.test.ts for the new path expansion functions:

Test Suite: expandExcludePath tests - Tests for single path expansion (6 tests):

Test Name Purpose
Expand ${workspaceFolder} variable Verifies ${workspaceFolder} is correctly replaced with the workspace folder path
Expand multiple ${workspaceFolder} variables Tests that multiple occurrences of ${workspaceFolder} in a single path are all expanded
Resolve relative path Verifies relative paths like subdir/nested are resolved to absolute paths relative to the workspace folder
Absolute path remains unchanged Ensures absolute paths (e.g., D:\Other\Path or /other/path) are not modified
Expand ${workspaceFolder} and resolve relative path Tests parent directory navigation (e.g., ${workspaceFolder}/../other)
${workspaceFolder:name} fallback when folder name not found Tests that unresolved ${workspaceFolder:Name} variables are left as-is and treated as relative paths

Test Suite: expandExcludePaths tests - Tests for array path expansion (2 tests):

Test Name Purpose
Expand multiple paths Verifies correct expansion of an array containing mixed path types (variables, relative, absolute)
Empty array returns empty array Edge case test ensuring empty input returns empty output

Test Helper Functions:

  • createMockWorkspaceFolder(): Creates mock vscode.WorkspaceFolder objects for testing
  • testBasePath: Platform-aware base path for cross-platform test compatibility
  • getExpectedPath(): Helper to construct expected paths using the same normalization as the code under test

Windows Test Fix

Fixed Windows unit test failures by updating tests to use util.lightNormalizePath() instead of path.normalize() for expected values. The codebase's lightNormalizePath() function converts Windows backslashes to forward slashes and uses vscode.Uri.file().fsPath which returns lowercase drive letters on Windows. The tests now use the same normalization approach as the code under test for cross-platform consistency.

Original prompt

This section details on the original issue you should resolve

<issue_title>[Feature] Support ${workspaceFolder} / relative paths in cmake.exclude for multi-root workspaces</issue_title>
<issue_description>### Request Overview

cmake.exclude in CMake Tools (v1.22.20) only accepts absolute paths.
Variable paths such as ${workspaceFolder} / ${workspaceFolder:Name} and relative paths are not resolved, so excluded folders are still treated as CMake projects.

This prevents using cmake.exclude in shared or portable workspaces.

Request:
Add support for ${workspaceFolder} and relative paths in cmake.exclude.

Reference: PR #4440.

Additional Information

No response</issue_description>

<agent_instructions>You are Copilot coding agent acting as a senior maintainer/contributor for the VS Code extension repository microsoft/vscode-cmake-tools.

You are deeply familiar with CMake, CMake Presets, CTest, kit/toolchain selection, VS Code extension APIs, and the architecture of this repo.

Your job is to resolve the assigned GitHub issue in a maintainable way, matching existing patterns and UX.

When approaching the issue, follow these steps exactly:

  1. Read and understand the whole issue thread, analyze any comments and links, and identify the problem/request before starting work on the solution.
  2. If the issue is a regression, look at previous commits and PRs. Note in the PR comments where you think the regression occurred and in what PR/commit.
  3. Before generating a solution, see if there is an existing solution pattern elsewhere in the vscode-cmake-tools repo that you can follow. Consider also looking at the docs hosted in the repo as well.
  4. Always follow existing structures and conventions for maintainability. Be aware of regression risks.
  5. Always add tests covering the changes if it makes sense. Also make sure to update the existing tests to handle the changes if needed.
  6. For localization changes, never update any files under the i18n directory. You can assume that the changes you need to happen in those files will by updated later based on the localization changes you made elsewhere in the repo.
  7. Once you have come up with a solution to the assigned issue, update the description with the root cause of the issue, the solution to the issue, how the solution addresses the issue, what tests where added/updated and why, and how to manually verify the changes especially focusing on how to test regression risks.
  8. Make sure to update the changelog with an explanation of how the solution affects the user experience (not what we changed internally). For improvements and bugs, link the assigned issue. For features, link the PR with the feature changes.

Note: When addressing Intellisense issues, you may need to look at how the CMake Tools extension interfaces with the Cpp Tools extension. The Cpp Tools extension handles C and C++ Intellisense by allowing other extensions to interface with it. You may want to look at the vscode-cpptools repo to understand how the CMake Tools extension interfaces with the Cpp Tools extension. Here is the Cpp Tools extension repo link (vscode-cpptools): https://github.com/microsoft/vscode-cpptools</agent_instructions>

Comments on the Issue (you are @copilot in this section)


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot AI and others added 3 commits February 3, 2026 20:42
…exclude

Co-authored-by: snehara99 <113148726+snehara99@users.noreply.github.com>
Co-authored-by: snehara99 <113148726+snehara99@users.noreply.github.com>
Co-authored-by: snehara99 <113148726+snehara99@users.noreply.github.com>
Copilot AI changed the title [WIP] Add support for relative paths in cmake.exclude feat: support ${workspaceFolder} and relative paths in cmake.exclude Feb 3, 2026
Copilot AI requested a review from snehara99 February 3, 2026 20:50
@snehara99
Copy link
Copy Markdown
Contributor

@copilot can you document the test updates

Co-authored-by: snehara99 <113148726+snehara99@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Feb 3, 2026

@copilot can you document the test updates

Added test documentation in commit 9511d75. The PR description now includes a detailed "Test Updates Documentation" section with:

  • Test suite descriptions and individual test purposes
  • Table format for easy reference
  • Explanation of helper functions
  • Rationale for why each test was added

Copilot AI added a commit that referenced this pull request Feb 3, 2026
Co-authored-by: snehara99 <113148726+snehara99@users.noreply.github.com>
@snehara99
Copy link
Copy Markdown
Contributor

@copilot can you link the feature PR (#4689 ) in the changelog update?

Co-authored-by: snehara99 <113148726+snehara99@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Feb 3, 2026

@copilot can you link the feature PR (#4689 ) in the changelog update?

Added PR link in commit 5d1ad27. The changelog entry now includes [#4689](https://github.com/microsoft/vscode-cmake-tools/pull/4689).

snehara99 added a commit that referenced this pull request Feb 9, 2026
…n build directory changes (#4694)

* Initial plan

* Fix terminal cwd not updating when build directory changes

Co-authored-by: snehara99 <113148726+snehara99@users.noreply.github.com>

* Fix issue number reference from #4689 to #4549

Co-authored-by: snehara99 <113148726+snehara99@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: snehara99 <113148726+snehara99@users.noreply.github.com>
@snehara99
Copy link
Copy Markdown
Contributor

@copilot the windows unit tests don't pass. Can you see if it's a code issue or a test issue? Update the solution based on what you find and explain why you made the changes you did in a comment on the PR. Here are the logs:

  expandExcludePath tests
    1) Expand ${workspaceFolder} variable
    2) Expand multiple ${workspaceFolder} variables
    3) Resolve relative path
    4) Absolute path remains unchanged
    5) Expand ${workspaceFolder} and resolve relative path
    6) ${workspaceFolder:name} fallback when folder name not found
  expandExcludePaths tests
    7) Expand multiple paths
    √ Empty array returns empty array
  163 passing (3m)
  7 failing
  1) expandExcludePath tests
       Expand ${workspaceFolder} variable:

      AssertionError: expected 'c:/Projects/MyProject/subdir' to equal 'C:\Projects\MyProject\subdir'
      + expected - actual

      -c:/Projects/MyProject/subdir
      +C:\Projects\MyProject\subdir
      
  	at Context.<anonymous> (d:\a\vscode-cmake-tools\vscode-cmake-tools\out\test\unit-tests\util.test.js:77:39)
  	at process.processImmediate (node:internal/timers:485:21)

  2) expandExcludePath tests
       Expand multiple ${workspaceFolder} variables:

      AssertionError: expected 'c:/Projects/MyProject/foo/c:/Projects…' to equal 'C:\Projects\MyProject\foo\C:\Projects…'
      + expected - actual

      -c:/Projects/MyProject/foo/c:/Projects/MyProject/bar
      +C:\Projects\MyProject\foo\C:\Projects\MyProject\bar
      
  	at Context.<anonymous> (d:\a\vscode-cmake-tools\vscode-cmake-tools\out\test\unit-tests\util.test.js:83:39)
  	at process.processImmediate (node:internal/timers:485:21)

  3) expandExcludePath tests
       Resolve relative path:

      AssertionError: expected 'c:/Projects/MyProject/subdir/nested' to equal 'C:\Projects\MyProject\subdir\nested'
      + expected - actual

      -c:/Projects/MyProject/subdir/nested
      +C:\Projects\MyProject\subdir\nested
      
  	at Context.<anonymous> (d:\a\vscode-cmake-tools\vscode-cmake-tools\out\test\unit-tests\util.test.js:89:39)
  	at process.processImmediate (node:internal/timers:485:21)

  4) expandExcludePath tests
       Absolute path remains unchanged:

      AssertionError: expected 'D:/Other/Path' to equal 'D:\Other\Path'
      + expected - actual

      -D:/Other/Path
      +D:\Other\Path
      
  	at Context.<anonymous> (d:\a\vscode-cmake-tools\vscode-cmake-tools\out\test\unit-tests\util.test.js:96:39)
  	at process.processImmediate (node:internal/timers:485:21)

  5) expandExcludePath tests
       Expand ${workspaceFolder} and resolve relative path:

      AssertionError: expected 'c:/Projects/other' to equal 'C:\Projects\other'
      + expected - actual

      -c:/Projects/other
      +C:\Projects\other
      
  	at Context.<anonymous> (d:\a\vscode-cmake-tools\vscode-cmake-tools\out\test\unit-tests\util.test.js:102:39)
  	at process.processImmediate (node:internal/timers:485:21)

  6) expandExcludePath tests
       ${workspaceFolder:name} fallback when folder name not found:

      AssertionError: expected 'c:/Projects/MyProject/${workspaceFold…' to equal 'C:\Projects\MyProject\${workspaceFold…'
      + expected - actual

      -c:/Projects/MyProject/${workspaceFolder:NonExistentFolder}/subdir
      +C:\Projects\MyProject\${workspaceFolder:NonExistentFolder}\subdir
      
  	at Context.<anonymous> (d:\a\vscode-cmake-tools\vscode-cmake-tools\out\test\unit-tests\util.test.js:114:39)
  	at process.processImmediate (node:internal/timers:485:21)

  7) expandExcludePaths tests
       Expand multiple paths:

      AssertionError: expected 'c:/Projects/MyProject/subdir1' to equal 'C:\Projects\MyProject\subdir1'
      + expected - actual

Error: 7 tests failed.
	at d:\a\vscode-cmake-tools\vscode-cmake-tools\out\test\unit-tests\index.js:41:27
	at done (d:\a\vscode-cmake-tools\vscode-cmake-tools\node_modules\mocha\lib\mocha.js:1053:7)
Extension host test runner error Error: 7 tests failed.
	at d:\a\vscode-cmake-tools\vscode-cmake-tools\out\test\unit-tests\index.js:41:27
	at done (d:\a\vscode-cmake-tools\vscode-cmake-tools\node_modules\mocha\lib\mocha.js:1053:7)
      -c:/Projects/MyProject/subdir1
      +C:\Projects\MyProject\subdir1
      
  	at Context.<anonymous> (d:\a\vscode-cmake-tools\vscode-cmake-tools\out\test\unit-tests\util.test.js:127:43)
  	at process.processImmediate (node:internal/timers:485:21)

Asking native host service to exit with code 1.
[main 2026-02-03T21:53:29.243Z] Extension host with pid 1268 exited with code: 0, signal: unknown.
Exit code:   1
Failed
Failed to run tests
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
Error: Process completed with exit code 1.

Co-authored-by: snehara99 <113148726+snehara99@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Feb 9, 2026

@copilot the windows unit tests don't pass. Can you see if it's a code issue or a test issue? Update the solution based on what you find and explain why you made the changes you did in a comment on th...

This was a test issue, not a code issue. Fixed in commit 32e941f.

Root cause: The tests were using path.normalize() to construct expected values, which on Windows returns paths with backslashes (C:\Projects\...). However, the actual code uses lightNormalizePath() which:

  1. Converts all backslashes to forward slashes (line 105-107 in util.ts)
  2. Gets paths from vscode.Uri.file().fsPath which on Windows returns lowercase drive letters (c:/...)

Fix: Updated the tests to use util.lightNormalizePath() and folder.uri.fsPath instead of path.normalize() and testBasePath directly, ensuring the expected values match the actual normalization behavior used by the code under test.

@Omotola Omotola marked this pull request as ready for review March 7, 2026 02:44
@Omotola Omotola marked this pull request as draft March 7, 2026 02:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature] Support ${workspaceFolder} / relative paths in cmake.exclude for multi-root workspaces

2 participants