Skip to content

Commit 3c9a3b4

Browse files
CopilotOmotolasnehara99
authored
Fix bookmark build target resolution to use correct outline lookup method (#4784)
* Initial plan * Fix bookmarked targets running full build instead of specific target (#4771) Co-authored-by: Omotola <[email protected]> * Add error logging when bookmark target cannot be resolved Co-authored-by: Omotola <[email protected]> * Fix project selection for bookmark builds using platformNormalizePath Co-authored-by: Omotola <[email protected]> * Add fallback resolution for bookmark targets via project outline lookup Co-authored-by: Omotola <[email protected]> * Revert resolveTargetNode to original working version without outline fallback Co-authored-by: Omotola <[email protected]> * Remove accidentally committed .npmrc.bak Co-authored-by: Omotola <[email protected]> * Fix resolveTargetNode fallback to use correct findTargetNodeById method The previous fallback (from automated reviewer suggestion) called getNodeById which doesn't exist on ProjectOutline, making it silently fail. The correct method is findTargetNodeById. This fallback provides defense-in-depth alongside the existing reattachTargets() mechanism for edge cases where the outline is populated but reattachTargets() hasn't run yet. Co-authored-by: snehara99 <[email protected]> --------- Co-authored-by: copilot-swe-agent[bot] <[email protected]> Co-authored-by: Omotola <[email protected]> Co-authored-by: Omotola <[email protected]> Co-authored-by: snehara99 <[email protected]>
1 parent 7d61e66 commit 3c9a3b4

2 files changed

Lines changed: 50 additions & 8 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ Improvements:
2828

2929
Bug Fixes:
3030
- Fix `cmake.buildTask` build failures not aborting debug launches. When `${command:cmake.launchTargetPath}` is used in `launch.json`, a failed build now correctly prevents the stale executable from being launched. [#3389](https://github.com/microsoft/vscode-cmake-tools/issues/3389)
31+
- Fix bookmarked targets running a full build instead of building only the specific target when triggered from the Bookmarks view. [#4771](https://github.com/microsoft/vscode-cmake-tools/issues/4771)
3132
- Fix `cmake.compileFile` command truncating long compile commands at ~1024 characters on macOS. The command is now sent to the terminal in chunks to avoid VS Code terminal buffer limitations. [#4470](https://github.com/microsoft/vscode-cmake-tools/issues/4470)
3233
- Fix configure/build sometimes using stale preset values when unsaved changes to included preset files are auto-saved before configure. The extension now explicitly refreshes presets from disk after saving, instead of relying solely on the asynchronous file watcher. [#4502](https://github.com/microsoft/vscode-cmake-tools/issues/4502)
3334
- Reduce overly verbose logging when CMake configure or build fails. The Output panel no longer floods with duplicated output, and the channel is only revealed on error rather than unconditionally. [#4749](https://github.com/microsoft/vscode-cmake-tools/issues/4749)

src/extension.ts

Lines changed: 49 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ import { StateManager } from './state';
3131
import { cmakeTaskProvider, CMakeTaskProvider } from '@cmt/cmakeTaskProvider';
3232
import * as telemetry from '@cmt/telemetry';
3333
import { ProjectOutline, ProjectNode, TargetNode, SourceFileNode, WorkspaceFolderNode, BaseNode, DirectoryNode, CTestTestNode } from '@cmt/ui/projectOutline/projectOutline';
34-
import { BookmarksProvider } from '@cmt/ui/bookmarks';
34+
import { BookmarksProvider, BookmarkNode } from '@cmt/ui/bookmarks';
3535
import * as util from '@cmt/util';
3636
import { ProgressHandle, DummyDisposable, reportProgress, runCommand } from '@cmt/util';
3737
import { DEFAULT_VARIANTS } from '@cmt/kits/variant';
@@ -1346,10 +1346,10 @@ export class ExtensionManager implements vscode.Disposable {
13461346
if (!projects || projects.length === 0) {
13471347
return activeProject;
13481348
} else {
1349-
// Choose project by corresponding source directory
1350-
return projects.find(project => sourceDir && (path.normalize(sourceDir) === path.normalize(project.folderPath)))
1349+
// Choose project by corresponding source directory (use platformNormalizePath for case-insensitive matching on Windows)
1350+
return projects.find(project => sourceDir && (util.platformNormalizePath(sourceDir) === util.platformNormalizePath(project.folderPath)))
13511351
// Choose project by folder of active project
1352-
?? projects.find(project => activeProject?.folderPath === project.folderPath)
1352+
?? projects.find(project => activeProject && (util.platformNormalizePath(activeProject.folderPath) === util.platformNormalizePath(project.folderPath)))
13531353
// Fallback to first project
13541354
?? projects[0];
13551355
}
@@ -2504,6 +2504,27 @@ async function setup(context: vscode.ExtensionContext, progress?: ProgressHandle
25042504
context.subscriptions.push(vscode.commands.registerCommand('cmake.getSettingsChangePromise', () => getSettingsChangePromise()));
25052505
}
25062506

2507+
// Helper to resolve a BookmarkNode to its underlying TargetNode
2508+
const resolveTargetNode = (what: TargetNode | BookmarkNode): TargetNode | undefined => {
2509+
if (what instanceof TargetNode) {
2510+
return what;
2511+
}
2512+
if (what instanceof BookmarkNode) {
2513+
// Fast path: the bookmark is already attached to a live TargetNode.
2514+
if (what.bookmark.sourceNode instanceof TargetNode) {
2515+
return what.bookmark.sourceNode;
2516+
}
2517+
// Fallback: try to resolve by stable id via the current project outline.
2518+
const node = ext.getProjectOutline().findTargetNodeById(what.bookmark.id);
2519+
if (node instanceof TargetNode) {
2520+
what.bookmark.sourceNode = node;
2521+
return node;
2522+
}
2523+
log.error(localize('bookmark.target.not.resolved', 'Bookmark "{0}" could not be resolved to a target. The project may need to be reconfigured.', what.bookmark.name));
2524+
}
2525+
return undefined;
2526+
};
2527+
25072528
context.subscriptions.push(...[
25082529
// Special commands that don't require logging or separate error handling
25092530
vscode.commands.registerCommand('cmake.outline.configureAll', () => runCommand('configureAll')),
@@ -2609,10 +2630,30 @@ async function setup(context: vscode.ExtensionContext, progress?: ProgressHandle
26092630
}),
26102631
vscode.commands.registerCommand('cmake.outline.build', (what: ProjectNode) => runCommand('build', what.folder, "all", what.sourceDirectory)),
26112632
vscode.commands.registerCommand('cmake.outline.clean', (what: ProjectNode) => runCommand('build', what.folder, "clean", what.sourceDirectory)),
2612-
vscode.commands.registerCommand('cmake.outline.buildTarget', (what: TargetNode) => runCommand('build', what.folder, what.name, what.sourceDir)),
2613-
vscode.commands.registerCommand('cmake.outline.runUtilityTarget', (what: TargetNode) => runCommand('build', what.folder, what.name, what.sourceDir)),
2614-
vscode.commands.registerCommand('cmake.outline.debugTarget', (what: TargetNode) => runCommand('debugTarget', what.folder, what.name, what.sourceDir)),
2615-
vscode.commands.registerCommand('cmake.outline.launchTarget', (what: TargetNode) => runCommand('launchTarget', what.folder, what.name, what.sourceDir)),
2633+
vscode.commands.registerCommand('cmake.outline.buildTarget', (what: TargetNode | BookmarkNode) => {
2634+
const target = resolveTargetNode(what);
2635+
if (target) {
2636+
return runCommand('build', target.folder, target.name, target.sourceDir);
2637+
}
2638+
}),
2639+
vscode.commands.registerCommand('cmake.outline.runUtilityTarget', (what: TargetNode | BookmarkNode) => {
2640+
const target = resolveTargetNode(what);
2641+
if (target) {
2642+
return runCommand('build', target.folder, target.name, target.sourceDir);
2643+
}
2644+
}),
2645+
vscode.commands.registerCommand('cmake.outline.debugTarget', (what: TargetNode | BookmarkNode) => {
2646+
const target = resolveTargetNode(what);
2647+
if (target) {
2648+
return runCommand('debugTarget', target.folder, target.name, target.sourceDir);
2649+
}
2650+
}),
2651+
vscode.commands.registerCommand('cmake.outline.launchTarget', (what: TargetNode | BookmarkNode) => {
2652+
const target = resolveTargetNode(what);
2653+
if (target) {
2654+
return runCommand('launchTarget', target.folder, target.name, target.sourceDir);
2655+
}
2656+
}),
26162657
vscode.commands.registerCommand('cmake.outline.setDefaultTarget', (what: TargetNode) => runCommand('setDefaultTarget', what.folder, what.name, what.sourceDir)),
26172658
vscode.commands.registerCommand('cmake.outline.setLaunchTarget', (what: TargetNode) => runCommand('selectLaunchTarget', what.folder, what.name, what.sourceDir)),
26182659
vscode.commands.registerCommand('cmake.outline.revealInCMakeLists', (what: TargetNode) => what.openInCMakeLists()),

0 commit comments

Comments
 (0)