Skip to content

Fix stale preset state on included file changes (#4777)#4778

Open
Copilot wants to merge 3 commits intomainfrom
copilot/fix-cmake-settings-refresh
Open

Fix stale preset state on included file changes (#4777)#4778
Copilot wants to merge 3 commits intomainfrom
copilot/fix-cmake-settings-refresh

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 2, 2026

This change addresses item #4777

This changes visible behavior for preset file watching and reconfiguration

The following changes are proposed:

  • Unify FileWatcher event handling: All filesystem events (change, create, delete) now use a single debounced callback. Previously, onDidCreate had a separate non-debounced handler, causing a race condition when tools like Conan regenerate included files via atomic write (delete→create): the delete would trigger reapplyPresets() while the file was absent, rebuilding the watcher list without the included file, so the subsequent create event was silently lost.
  • Detect root presets file creation inside reapplyPresets(): Replaced the separate onCreatePresetsFile() handler with a before/after check of presetsFileExist to call updateActiveProject() only when a root presets file transitions from absent to present.
  • Refresh presets in configureInternal(): Explicit user commands (configure, clean-configure, etc.) now call reapplyPresets() before proceeding, so they never depend on the async file watcher having already processed disk changes.
  • Update unit tests to validate unified debouncing and atomic write (delete+create) handling.
  • Add CHANGELOG entry.

Other Notes/Information

The ensureConfigured() path already had a reapplyPresets() call (added for #4502). The new call in configureInternal() covers the remaining code paths: direct configure, clean-configure, and clean-configure-with-debugger. Since reapplyPresets() serializes concurrent calls via _reapplyInProgress, double-calls from ensureConfigured()configureInternal() are effectively no-ops if presets haven't changed on disk.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • 40vvsblobprodwus2135.vsblob.vsassets.io
    • Triggering command: /home/REDACTED/work/_temp/ghcca-node/node/bin/node node /usr/local/bin/yarn install --frozen-lockfile (dns block)
  • 78kvsblobprodwus2152.vsblob.vsassets.io
    • Triggering command: /home/REDACTED/work/_temp/ghcca-node/node/bin/node node /usr/local/bin/yarn install --frozen-lockfile (dns block)
  • b53vsblobprodwus2154.vsblob.vsassets.io
    • Triggering command: /home/REDACTED/work/_temp/ghcca-node/node/bin/node node /usr/local/bin/yarn install --frozen-lockfile (dns block)
  • km4vsblobprodwus2183.vsblob.vsassets.io
    • Triggering command: /home/REDACTED/work/_temp/ghcca-node/node/bin/node node /usr/local/bin/yarn install --frozen-lockfile (dns block)
  • l7ivsblobprodwus2133.vsblob.vsassets.io
    • Triggering command: /home/REDACTED/work/_temp/ghcca-node/node/bin/node node /usr/local/bin/yarn install --frozen-lockfile (dns block)
  • v41vsblobprodwus2175.vsblob.vsassets.io
    • Triggering command: /home/REDACTED/work/_temp/ghcca-node/node/bin/node node /usr/local/bin/yarn install --frozen-lockfile (dns block)
  • vd2vsblobprodwus2150.vsblob.vsassets.io
    • Triggering command: /home/REDACTED/work/_temp/ghcca-node/node/bin/node node /usr/local/bin/yarn install --frozen-lockfile (dns block)
  • wztvsblobprodwus2155.vsblob.vsassets.io
    • Triggering command: /home/REDACTED/work/_temp/ghcca-node/node/bin/node node /usr/local/bin/yarn install --frozen-lockfile (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Original prompt

This section details on the original issue you should resolve

<issue_title>[Bug] Changes in file included from CMakeUserPreset.json didn't applied until VS Code restart</issue_title>
<issue_description>### Brief Issue Summary

In our project we're using conan for managing thirdpartys. When I run the conan install command it will generate the following CMakeUserPreset.json file in the root directory:

{
    "version": 4,
    "vendor": {
        "conan": {}
    },
    "include": [
        "build/generated/CMakePresets.json"
    ]
}

Current behavior:
Project settings were generated in the included build/generated/CMakePresets.json If VS Code is open when the generated build/generated/CMakePresets.json file is changed it won't affect the CMake variables and settings used for configuration. Even if I use the Delete Cache / Reconfigure the CMake plugin will use the old "cached" settings. The only solution to make it work is to close and reopen VS Code.
Expected behavior:
The changes in the build/generated/CMakePresets.json is detected and a new configuration step is triggered with the new settings.

CMake Tools Diagnostics

{
  "os": "win32",
  "vscodeVersion": "1.109.5",
  "cmtVersion": "1.22.28",
  "configurations": [
    {
      "folder": "c:\\work\\git\\temp_project.git",
      "cmakeVersion": "3.31.2",
      "configured": true,
      "generator": "Visual Studio 17 2022",
      "usesPresets": true,
      "compilers": {}
    }
  ],
  "cpptoolsIntegration": {
    "isReady": true,
    "hasCodeModel": true,
    "activeBuildType": "Debug",
    "buildTypesSeen": [
      "Debug",
      "Release",
      "MinSizeRel",
      "RelWithDebInfo"
    ],
    "requests": [],
    "responses": [],
    "partialMatches": [],
    "targetCount": 44,
    "executablesCount": 2,
    "librariesCount": 19,
    "targets": []
  },
  "settings": [
    {
      "communicationMode": "automatic",
      "useCMakePresets": "auto",
      "configureOnOpen": true
    }
  ]
}

Debug Log

Can't share the debug output

Additional Information

No response</issue_description>

<agent_instructions>You are a senior maintainer of vscode-cmake-tools. Fix the bug described in issue #4777 - #4777 : changes to files referenced via the include directive in CMakePresets.json or CMakeUserPresets.json are not detected by the extension until VS Code is restarted. Even "Delete Cache / Reconfigure" does not pick up the new content.

Context

The user has a CMakeUserPresets.json that includes a generated file:

{
    "version": 4,
    "vendor": { "conan": {} },
    "include": ["build/generated/CMakePresets.json"]
}

When an external tool (e.g., Conan) regenerates build/generated/CMakePresets.json, the extension continues using stale cached preset state. The only workaround is restarting VS Code.

Investigation Guidance

The bug likely involves two interacting subsystems. You must trace through both VERY carefully and verify whether the analysis below holds before implementing any changes.

Area 1: FileWatcher event handling for included files

Start by examining the FileWatcher class and watchPresetsChange() in src/presets/presetsController.ts. The FileWatcher currently receives two separate callbacks: a changeHandler (wired to onDidChange and onDidDelete) and a createHandler (wired to onDidCreate). The changeHandler calls reapplyPresets() while the createHandler calls onCreatePresetsFile().

Investigate whether this distinction causes problems for included files. The _referencedFiles list contains all files in the include chain, not just root preset files. The onCreatePresetsFile() path was designed for when CMakePresets.json or CMakeUserPresets.json themselves are freshly created — it calls updateActiveProject() in addition to reapplyPresets(). Consider whether applying this create-specific handler to included files introduces issues.

Specifically, examine what happens when an external tool regenerates an included file via atomic write (delete + create, or write-to-temp + rename). The OS may emit a delete followed by a create event. Trace what happens when onDidDelete fires reapplyPresets() while the file is momentarily absent — does mergeIncludeFiles() in src/presets/presetsParser.ts fail the expansion with errors, setting the preset state to undefined? If so, does the subsequent onDidCreate event reliably recover, or can it be lost due to watcher disposal during the rebuild?

One possible fix direction: unify the FileWatcher so all filesystem events (change, create, delete) trigger the same debounced reload path, and remove the separate create handler. The onCreatePresetsFile() behavior (updateActiveProject()) could instead be detected inside reapplyPresets() by comparing the before/after state of presetsFileExists, transitioning from `...


🔒 GitHub Advanced Security automatically protects Copilot coding agent pull requests. You can protect all pull requests by enabling Advanced Security for your repositories. Learn more about Advanced Security.

Copilot AI changed the title [WIP] Fix bug with CMake settings not refreshing in VS Code Fix stale preset state on included file changes (#4777) Mar 2, 2026
@hanniavalera hanniavalera marked this pull request as ready for review March 2, 2026 16:13
@hanniavalera hanniavalera force-pushed the copilot/fix-cmake-settings-refresh branch 2 times, most recently from 3392fc6 to 207f65a Compare March 2, 2026 16:51
Copilot AI and others added 2 commits March 2, 2026 12:36
- Unify FileWatcher to use single debounced callback for all events
  (change/create/delete), fixing race condition when external tools
  regenerate included files via atomic write (delete + create)
- Detect root presets file creation inside reapplyPresets() by comparing
  before/after presetsFileExists state instead of separate handler
- Add reapplyPresets() call in configureInternal() so explicit user
  commands always read fresh preset state from disk
- Update tests to reflect unified event handling
- Add CHANGELOG entry

Co-authored-by: hanniavalera <90047725+hanniavalera@users.noreply.github.com>
Co-authored-by: hanniavalera <90047725+hanniavalera@users.noreply.github.com>
@hanniavalera hanniavalera force-pushed the copilot/fix-cmake-settings-refresh branch from 207f65a to 29655f6 Compare March 2, 2026 20:36
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.

[Bug] Changes in file included from CMakeUserPreset.json didn't applied until VS Code restart

2 participants